Berechtigung in gespeicherter Prozedur auswählen?


8

Ich habe einem Benutzer die Ausführungsberechtigung für eine gespeicherte Prozedur erteilt, die dynamisches SQL verwendet. Aber wenn er versucht, es auszuführen, bekommt er den Fehler:

Die SELECT-Berechtigung wurde für das Objekt '[Tabellenname]', Datenbank '[Datenbankname]', Schema 'dbo' verweigert.

Muss dem Benutzer die Berechtigung für Tabellen erteilt werden, die von der gespeicherten Prozedur verwendet werden? Das würde für mich keinen Sinn ergeben.

Antworten:


5

Ok, auf der Grundlage des obigen Kommentars und gemäß meinem Verdacht - es scheint, als ob Sie versuchen, dynamisches SQL in Ihrer gespeicherten Prozedur auszuführen.

Was Sie beachten müssen, ist, dass es dabei nicht im Kontext der gespeicherten Prozedur ausgeführt wird, sondern in einer neuen Sitzung. Aus diesem Grund ist die Tatsache, dass die Anweisung innerhalb einer gespeicherten Prozedur aufgerufen wird, ein strittiger Punkt, und Sie müssen explizite Berechtigungen für die Objekte erteilen, die Ihr dynamisches SQL verwendet.

Wenn Sie dies nicht möchten, würde ich Ihre gespeicherte Prozedur so umgestalten, dass kein dynamisches SQL verwendet wird.

Der folgende Link von Microsoft soll Ihnen bei Ihrem Problem helfen:

PRB: Sicherheitskontext dynamischer SQL-Anweisungen in einer gespeicherten Prozedur (Wayback Machine-Archiv)

Dieses Verhalten tritt auf, weil eine dynamische Ausführungsabfrage (sp_executesql oder EXECUTE) in einem von der gespeicherten Hauptprozedur getrennten Kontext ausgeführt wird. Es wird im Sicherheitskontext des Benutzers ausgeführt, der die gespeicherte Prozedur ausführt, und nicht im Sicherheitskontext des Eigentümers der gespeicherten Prozedur.

Dies wird auch im (aktuelleren) Microsoft Docs-Artikel erläutert:

Schreiben von Secure Dynamic SQL in SQL Server

Das Ausführen dynamisch erstellter SQL-Anweisungen in Ihrem Prozedurcode unterbricht die Besitzerkette und veranlasst SQL Server, die Berechtigungen des Aufrufers anhand der Objekte zu überprüfen, auf die das dynamische SQL zugreift.


2

Es hört sich so an, als gäbe es verschiedene Eigentümer der Prozedur sowie des zugrunde liegenden Objekts, das von SELECT abgefragt wird. Dies alles hat mit Besitzerketten zu tun . Im folgenden Beispiel finden Sie eine kurze Erklärung und Demonstration dessen, wovon ich spreche:

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

Wenn Sie den Besitz Ihrer Objekte herausfinden möchten, können Sie die folgende Abfrage ausführen (natürlich mit Änderung der WHERE-Klausel, um Ihre spezifischen Objektnamen einzuschließen):

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'
);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.