Selezionare l'autorizzazione all'interno della procedura memorizzata?


8

Ho concesso a un utente l'esecuzione dell'autorizzazione per una procedura memorizzata che utilizza SQL dinamico. Ma quando tenta di eseguirlo, ottiene l'errore:

L'autorizzazione SELECT è stata negata sull'oggetto '[nome tabella]', database '[nome database]', schema 'dbo'.

L'utente deve disporre dell'autorizzazione per le tabelle utilizzate dalla procedura memorizzata? Non avrebbe davvero senso per me.

Risposte:


5

Ok, sulla base del commento sopra e secondo il mio sospetto - sembra che tu stia provando a eseguire SQL dinamico all'interno della tua procedura memorizzata.

Quello che devi ricordare è che quando lo fai non viene eseguito nel contesto della procedura memorizzata - viene eseguito all'interno di una nuova sessione. Per questo motivo, il fatto che l'istruzione venga chiamata all'interno di una procedura memorizzata è un punto controverso e sarà necessario concedere un'autorizzazione esplicita agli oggetti utilizzati dall'SQL dinamico.

Se non si desidera eseguire questa operazione, si riformattare la procedura memorizzata per non utilizzare SQL dinamico.

Il seguente link di Microsoft dovrebbe aiutarti con il tuo problema:

PRB: contesto di sicurezza delle istruzioni SQL dinamiche all'interno di una procedura memorizzata (archivio Wayback Machine)

Questo comportamento si verifica perché una query di esecuzione dinamica (sp_executesql o EXECUTE) viene eseguita in un contesto separato dalla procedura memorizzata principale; viene eseguito nel contesto di sicurezza dell'utente che esegue la procedura memorizzata e non nel contesto di sicurezza del proprietario della procedura memorizzata.

Questo è anche discusso nell'articolo (più attuale) di Microsoft Docs:

Scrittura sicura di SQL dinamico in SQL Server

L'esecuzione di istruzioni SQL create in modo dinamico nel codice procedurale interrompe la catena di proprietà, facendo sì che SQL Server controlli le autorizzazioni del chiamante rispetto agli oggetti a cui accede l'SQL dinamico.


2

Sembra che ci siano diversi proprietari della procedura e l'oggetto sottostante a cui SELECT sta interrogando. Tutto questo ha a che fare con le catene di proprietà . Vedi l'esempio seguente per una breve spiegazione e dimostrazione di cosa sto parlando:

use YourTestDatabase;
go

create login TestLogin1
with 
    password = 'password',
    check_policy = off;
go

create user TestUser1
for login TestLogin1;
go

create table Table1
(
    id int identity(1, 1) not null,
    SomeString varchar(30) not null
        default replicate('a', 30)
);
go

insert into Table1
values(default);
go 10

create proc Proc1
as
    select *
    from Table1;
go


grant execute
on Proc1
to TestUser1;
go

-- this works because permissions aren't checked
--  on Table1.  That is why TestUser1 can get the
--  result set without SELECT permissions on Table1
execute as user = 'TestUser1';
go

exec Proc1;
go

revert;
go

-- let's change the owner of Proc1 so that the 
--  ownership chain is broken and permissions are
--  checked on Table1
alter authorization
on Proc1
to TestUser1;
go

-- this no longer works because permissions are now
--  checked on Table1, which TestUser1 does not have
--  SELECT permissions on
execute as user = 'TestUser1';
go

exec Proc1;
go

revert;
go

Se vuoi scoprire la proprietà dei tuoi oggetti, puoi eseguire la query qui sotto (ovviamente cambiando la clausola WHERE per includere i tuoi nomi di oggetti specifici):

select
    o.name,
    o.type_desc,
    case
        when o.principal_id is null
            then sp.name
        else dp.name
    end as principal_name
from sys.objects o
inner join sys.schemas s
on o.schema_id = s.schema_id
left join sys.database_principals dp
on o.principal_id = dp.principal_id
left join sys.database_principals sp
on s.principal_id = sp.principal_id
where o.name in
(
    'Table1',
    'Proc1'
);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.