2014-12-03 6 views
5

In che modo SQL Server gestisce gli accessi in caso di ambiguità, ad esempio, esistono accessi sia per l'account utente Windows sia per un gruppo AD che contiene questo utente?Autorizzazioni a livello di database per un utente Windows con accesso creato sia per l'utente che contenente il gruppo di annunci?

Abbiamo riscontrato un piccolo problema con le autorizzazioni in SQL Server 2008 con utenti Windows dalla nostra Active Directory e gruppi da tale annuncio. Proverò a spiegare con un esempio.

Immaginare un utente di dominio Windows DOMAIN\myUser appartenente a un gruppo di annunci DOMAIN\SomeGroup.

In SQL Server, ho 2 database SomeAppDb e PublicDb.

L'obiettivo è che tutti gli utenti che sono membri di DOMAIN\SomeGroup dovrebbero essere in grado di accedere PublicDb, ma solo DOMAIN\myUser dovrebbero essere in grado di accedere a SomeAppDb.

Inizialmente, in SQL Server un account di accesso di Windows DOMAIN\SomeGroup (associato al gruppo dC) è stato creato per l'istanza, e un utente è stato creato nel database PublicDb con una corretta appartenenza a un ruolo, e che ha funzionato bene, gli utenti dal gruppo SomeGroup poteva accedere ai dati di cui avevano bisogno in PublicDb.

Per le esigenze di una nuova applicazione, abbiamo voluto fornire un accesso esplicito per db SomeAppDb all'utente DOMAIN\myUser, consentendo comunque l'accesso a PublicDb. Abbiamo quindi creato in SQL Server un account di accesso di Windows per DOMAIN\myUser, e un utente è stato creato nel database SomeAppDb, con una mappatura tra il 2.

Da quel momento, myUser potrebbe accedere SomeAppDb come previsto, ma potrebbe non accedere più PublicDb , e abbiamo avuto un errore come:

Cannot open database "PublicDb" requested by the login. The login failed. 
Login failed for user 'DOMAIN\myUser' 

mio intuito mi dice che quando l'utente accede l'istanza di SQL Server, SQL Server vede un account di accesso alle partite l'utente di Windows e ignora il login esistente per un gruppo che l'utente appartiene a.

Un approccio è quello di aggiungere esplicitamente l'accesso al db PublicDb per utente myUser, ma preferirei evitare quella soluzione in quanto obbliga ad aggiornare PublicDb ogni volta che vogliamo dare accesso a nuovi utenti che è esattamente quello che stavamo cercando di evitare inizialmente ... (lo abbiamo fatto come una soluzione temporanea, sperando di trovare un'opzione migliore).

Qualcun altro ha riscontrato questo problema? c'è un approccio migliore?

grazie in anticipo

+0

la mia domanda potrebbe essere spostata su http://dba.stackexchange.com? – tsimbalar

+0

Sei curioso di sapere se hai avuto la possibilità di testare qualcuno dei test suggeriti e verificare cose come l'appartenenza al gruppo, ecc.? –

+1

questa settimana sono impazzito, ma spero di immergermi un po 'più a fondo prima della fine della settimana. grazie – tsimbalar

risposta

7

mio intuito mi dice che quando l'utente accede l'istanza di SQL Server, SQL Server vede un account di accesso alle partite l'utente di Windows e ignora il login esistente per un gruppo cui appartiene l'utente a.

Questa intuizione non è corretta. E questa è una buona cosa perché il modo in cui si desidera che l'installazione di sicurezza funzioni è il modo in cui lo dovrebbe funzionare; le autorizzazioni sono additive. Ho appena riprodotto la configurazione e la creazione dell'accesso per l'accesso a Windows non ha avuto effetti negativi sulle autorizzazioni (ad es.accesso DB specifico) che sono stati assegnati solo all'accesso basato sul gruppo Windows. Sono persino in grado di impostare il database predefinito per l'accesso basato su accesso di Windows in un database accessibile solo tramite un'associazione correlata all'accesso basato sul gruppo di Windows. E sì, il mio test Login era solo un membro dei ruoli del server e del database public e ho verificato che qualsiasi database non esplicitamente mappato al Login basato su Windows o all'accesso basato su Login di Windows non era accessibile.

Quindi, sono abbastanza sicuro che qualcosa sia cambiato al di fuori di ciò che è stato menzionato o di qualche altra configurazione sta creando questa situazione. Ma prima, probabilmente dovremmo essere chiari sul problema esatto. La descrizione del problema afferma:

Da quel momento, myUser potrebbe accedere SomeAppDb come previsto, ma potrebbe non accedere più PublicDb

Ciò dovrebbe significare che myUser stato in grado di effettuare il login. Tuttavia, in qualche modo l'utente non è riuscito a passare a PublicDb tramite USE [PublicDb]? O stiamo parlando di qualcos'altro? Forse qualcos'altro come implicito dal messaggio di errore esatto:

Impossibile aprire il database "PublicDb" richiesto dal login. L'accesso non è riuscito. Accesso non riuscito per l'utente 'DOMINIO \ myUser'

Se myUser è stato registrato e semplicemente cambiando i database, o fare una query tra database, allora non ci sarebbe un "Accesso non riuscito" messaggio di errore. Questo mi porta a sospettare che il database predefinito (o il database specificato nella stringa di connessione) sia SomeAppDb e come detto, non ci siano problemi lì. Ma poi dovrebbe essere una stringa di connessione che specifica "PublicDb" che stava avendo il problema. In tal caso, sarebbe la stessa stringa di connessione, copiata e incollata (non ridigitata) perché qualcun altro lavori? Forse c'è una typeo, anche un carattere nascosto, nella stringa di connessione che specifica "PublicDb"? Gli unici modi in cui sono stato in grado di riprodurre tale errore è collegando tramite SQLCMD mentre specificando un database che:

  • non esistevano
  • esisteva, l'account ha avuto accesso, ma aveva quadrati parentesi intorno al nome (ad es -d "[PublicDb]")
  • esistito, ma il conto non ha avuto accesso a (significato, ci sono più cose da provare, come indicato di seguito ;-)

Se non è un problema di stringa di connessione, qui ci sono alcune cose da controllare :

  1. Mentre DOMAIN\myUser viene registrato in SQL Server, DOMAIN\myUser dovrebbe eseguire il seguente:

    -- http://msdn.microsoft.com/en-us/library/ms186271.aspx (IS_MEMBER) 
    SELECT IS_MEMBER(N'DOMAIN\SomeGroup'); 
    

    Se questo accesso è davvero in quel gruppo, allora verrà restituito un 1.In caso contrario, lo fa allora:

    • 0 significa che l'accesso è un login di Windows, ma non in quel gruppo, così è stato rimosso dal gruppo, o
    • NULL significa che questo non è un account di accesso di Windows (sembra improbabile dato che il nome di accesso in SQL Server ha un \ che non è un carattere valido per un accesso di SQL Server)
  2. Mentre DOMAIN\myUser viene registrato in SQL Server:

    1. Rimuovere quella correzione temporanea dell'utente DOMAIN\myUser in PublicDb.
    2. DOMAIN\myUser dovrebbe eseguire il seguente:

      SELECT HAS_DBACCESS(sd.[name]) AS [HasAccess], * 
      FROM sys.databases sd 
      ORDER BY 1 DESC, [name] ASC; 
      

      Vuol PublicDb compare nella lista?

  3. eseguire la seguente query:

    SELECT * 
    FROM sys.server_principals 
    WHERE [name] IN ('DOMAIN\myUser', 'DOMAIN\SomeGroup'); 
    

    controllare i seguenti campi: sid, type_desc e default_database_name. Assicurati che il "database predefinito" sia davvero un database. Potrebbe essere che il valore sia stato impostato in modo errato quando inizialmente hai aggiunto il Login per DOMAIN\myUser. Se non altro, forse prova a impostarlo su [master] per vedere se questo aggira l'errore. Se funziona, reimpostalo su [PublicDb].

  4. hanno "myUser" accedere a Windows, passare a un prompt dei comandi, ed eseguire:

    SQLCMD -E -Q"SELECT DB_NAME(), USER; USE [PublicDb]; SELECT DB_NAME(), USER;" 
    

    La prima riga restituita dovrebbe essere SomeAppDb DOMAIN\myUser. Quindi un messaggio su come cambiare i contesti del database. E poi dovrebbero vedere PublicDb DOMAIN\myUser.

    • Se sì, allora questo non è sicuramente un problema di "accesso db".
    • Se no, allora questo Login non fa più parte di quel Gruppo o qualcosa di specifico lo sta bloccando. Nel qual caso, è stato fatto qualcosa aggiungendo il Login specifico per DOMAIN\myUser oltre "un Utente è stato creato nel database SomeAppDb, con una mappatura tra il 2." come negare qualsiasi autorizzazione a livello di server o di livello di database?
  5. hanno "myUser" accedere a Windows, passare a un prompt dei comandi, ed eseguire:

    SQLCMD -E -Q"SELECT DB_NAME(), USER;" -d"PublicDb" 
    

    essi dovrebbero avere una fila restituita essere PublicDb DOMAIN\myUser. Se sì, allora questo non è sicuramente un problema di "accesso".

  6. Un test semplice sarebbe:
    1. creare un nuovo account Active Directory
    2. rendere questo conto un membro della 'DOMINIO \ QualcheGruppo'
    3. accedere a Windows come questo account
    4. connettersi a SQL Server
    5. Provare ad accedere a entrambi i database. Questo account dovrebbe essere in grado di accedere solo PublicDb
    6. Disconnetti da SQL Server
    7. creare un accesso a SQL Server per che Windows di test rappresentano
    8. Creazione di un utente (senza opzioni extra) in SomeAppDb per quella Login (ad es CREATE USER [DOMAIN\myUser] FOR LOGIN [DOMAIN\myUser])
    9. Connessione a SQL Server
    10. Provare ad accedere a entrambi i database. L'account dovrebbe ora essere in grado di.
  7. Un'ultima cosa da verificare sarebbe rimuovere tutti i pezzi che sembrano essere la causa di questo errore. Quindi, eliminare l'utente DOMAIN\myUser in SomeAppDb e quindi eliminare l'accesso DOMAIN\myUser. Se una di queste cose ha davvero causato questo errore, a questo punto DOMAIN\myUser dovrebbe essere in grado di accedere nuovamente a PublicDb.
  8. Quali altri gruppi di Windows è il login di Windows un membro (almeno quello che avrebbe un accesso)?
  9. Di che "appartenenza al ruolo" stavi parlando? Sono questi ruoli integrati o ruoli personalizzati?

P.S. La maggior parte dei post correlati, che galleggiano là fuori, che si occupano di questo stesso errore, finiscono per creare un login di SQL Server per utilizzare o aggiungere il login basato su Windows al ruolo "db_owner". Penso che entrambe queste soluzioni siano controproducenti e che i computer non siano arbitrari nel loro comportamento, quindi dobbiamo solo trovare la causa.

+1

grazie mille, controllerò un po 'di più la configurazione attuale e molto probabilmente segnerà la tua risposta come accettata, perché è piuttosto completa! – tsimbalar

+0

@tsimbalar grazie e nessun problema. Inoltre, se lo contrassegni come accettato prima di comprenderlo completamente (in modo che il bounty non vada a/dev/null ;-), continuerò ad aiutarti con esso fino a quando non verrà risolto. Ci deve essere almeno un caso documentato contenente una correzione da qualche parte sulla rete, quindi sono disposto a farlo fuori :) –

+1

ok, lo farò, ecco che arriva la taglia! : P – tsimbalar

Problemi correlati