it-swarm.it

Ricezione "L'autorizzazione SELECT è stata negata sull'oggetto" anche se è stata concessa

Sono un programmatore, non un dba ... so quanto basta per essere pericoloso.

Ho ereditato un database con un utente legacy che è un db_owner per il database. Non possiamo regolare l'autorizzazione di questo utente per tabelle, schemi, ecc. Esistenti, per motivi di lavoro, ma alcune nuove tabelle vengono create e voglio solo che questo utente abbia accesso a SELECT su di esse.

Le autorizzazioni sono state impostate per questo utente per queste tabelle in modo che tutto sia DENIED, tranne SELECT, che è impostato su GRANT.

Tuttavia, quando questo utente (dbadmin) tenta di eseguire un SELECT su una di queste tabelle (AccountingAudit), si verifica questo errore:

The SELECT permission was denied on the object 'AccountingAudit', database 'billing', schema 'dbo'.

Ho eseguito questo SQL per provare e vedere quali autorizzazioni sono impostate per questa tabella/utente:

select object_name(major_id) as object,
 user_name(grantee_principal_id) as grantee,
 user_name(grantor_principal_id) as grantor,
 permission_name,
 state_desc
from sys.database_permissions

E questo è quello che torno:

AccountingAudit dbadmin dbo ALTER   DENY
AccountingAudit dbadmin dbo CONTROL DENY
AccountingAudit dbadmin dbo DELETE  DENY
AccountingAudit dbadmin dbo INSERT  DENY
AccountingAudit dbadmin dbo REFERENCES  DENY
AccountingAudit dbadmin dbo SELECT  GRANT
AccountingAudit dbadmin dbo TAKE OWNERSHIP  DENY
AccountingAudit dbadmin dbo UPDATE  DENY
AccountingAudit dbadmin dbo VIEW DEFINITION DENY
AccountingAudit dbadmin dbo VIEW CHANGE TRACKING    DENY

Sembra che dovrebbe funzionare bene?

La chiamata SELECT che sto effettuando è un SELECT * FROM AccountingAudit molto semplice, all'interno di SSMS. Non sto facendo alcun sp_executesql speciale o qualcosa del genere.

Ho provato a concedere esplicitamente l'autorizzazione:

GRANT SELECT ON [dbo].AccountingAudit TO dbadmin

Questo non ha alcun effetto (perché, la query sopra mostra già che è stata concessa! ;-)

Ho cercato attraverso stackoverflow.com e altrove e non riesco a trovare nulla che non abbia ancora provato. Mi chiedo se abbia qualcosa a che fare con il modo in cui gli schemi sono impostati. (A questo punto so ben poco sugli schemi.)

Qualche idea? Grazie!

11
Mason G. Zhwiti

Non sono sicuro qui, ma sto per uscire su un arto. Penso che il tuo problema potrebbe riguardare il tuo DENY CONTROL disco. Vedi qui circa a metà pagina:

Negare l'autorizzazione CONTROL su un database nega implicitamente l'autorizzazione CONNECT sul database. Un'entità a cui è negata l'autorizzazione CONTROL su un database non sarà in grado di connettersi a quel database.

Mi rendo conto che l'esempio è per un database, ma prendo un altro livello granulare. A DENY CONTROL su un tavolo negherà tutto privilegi su di esso, immagino. Esegui un REVOKE CONTROL per sbarazzartene e vedere se questo risolve il problema.

In tal caso, dovrai inserire l'utente in un ruolo di database o negare loro i privilegi espliciti rispetto alla tabella.

10
Thomas Stringer
  1. Usa sp_DBPermissions stored procedure per esaminare le autorizzazioni.

    1. Assicurarsi DENY CONTROL non viene applicato alla tabella, oltre al comune DENY SELECT, DENY INSERT, DENY UPDATE, DENY DELETE e DENY REFERENCES.
    2. Se l'istruzione SELECT contiene funzioni con valori di tabella, assicurati che sia presente un EXECUTE AS OWNER sulla funzione con valori di tabella o un GRANT EXECUTE su di esso (e no DENY EXECUTE!). In questo caso, leggi il messaggio di errore più attentamente poiché probabilmente non dirà che l'autorizzazione SELECT è stata negata sulla tabella, ma invece è stato negato qualcosa riguardo a EXECUTE.
  2. Se l'utente è un utente o un gruppo di annunci, utilizzare il seguente script per determinare l'utente login_token(S):

EXECUTE AS LOGIN = 'EXAMPLEDOMAIN\JOHN.DOE';
SELECT * FROM sys.login_token;
REVERT;
  1. Guarda il piano di esecuzione attuale. Se l'errore si trova all'interno di una procedura memorizzata con SET NOCOUNT ON;, quindi il piano di esecuzione effettivo ti fornirà informazioni sulle quali potresti non prestare attenzione semplicemente guardando la scheda Messaggi in SSMS, poiché "Righe interessate" potrebbe essere al di fuori del tuo controllo.

    1. Cerca trigger o tabelle temporali.
  2. È possibile compilare l'istruzione come procedura memorizzata e SSMS "Visualizza dipendenze oggetti", nonché i trucchi delineati da Svetlana Golovko in Modi diversi per trovare le dipendenze degli oggetti di SQL Server

  3. Utilizzare l'evento di sicurezza di SQL Server Profiler "Evento di accesso agli oggetti dello schema di controllo" e le colonne "TextData" e "Operazione riuscita" per tenere traccia degli oggetti su cui SQL Server sta valutando le autorizzazioni. - Ho visto situazioni in cui sono state emesse due righe per questo evento e un valore indica Success = 1 e l'altro indica Success = 0. In questo scenario, l'unica soluzione che ho trovato funzionare è riavviare il server. Anche in esecuzione repadmin /syncall non ha risolto il problema, né avviato e arrestato l'applicazione (e quindi il pool di connessioni).

  4. Determinare le autorizzazioni effettive per l'accesso:

-- '<domain>\<username>' is a domain user in the group you wish to test
EXECUTE AS LOGIN = '<domain>\<username>';
SELECT * FROM fn_my_permissions('Database.Schema.Table', 'OBJECT');
REVERT;
  1. Se l'utente è legato a un utente o gruppo AD, considera di eseguire repadmin /syncall per imporre la sincronizzazione delle modifiche apportate in Active Directory tra i controller di dominio. - Se qualcuno conosce un buon modo per confrontare i valori correnti di due controller di dominio, per favore fatemelo sapere.

  2. Prima di prendere in considerazione un riavvio forzato dell'intero sistema, prova a eliminare tutte le connessioni attive per quell'utente. Il motivo è che l'utente ottiene il token di Windows dal DC che include i propri gruppi. Il token non verrà aggiornato fino a quando l'utente non riceverà un nuovo token, in genere disconnettendosi e quindi riconnettendosi .

  3. Riavvio rigido del sistema. Ha funzionato per me. Ancora non sicuro al 100% perché ancora. FARE SOLO QUESTO SE PUOI SOPRAVVIVERE I TEMPI! ATTENZIONE A FARE QUESTO MENTRE AVETE GRANDI OPERAZIONI ECCEZIONALI!

0
John Zabroski