下面的正确答案是什么?我本以为EXECUTE许可就足够了?谢谢!
该数据库具有一个名为Customersowned by的表UserA和另一个名为Ordersowned by的表UserB。你也有一个存储过程GetCustomerOrderInfo归UserB。GetCustomerOrderInfo从两个表中选择数据。您创建一个新用户UserC。您需要确保UserC可以调用该GetCustomerOrderInfo存储过程。您还只需要分配最低要求的权限即可UserC
Customers
UserA
Orders
UserB
GetCustomerOrderInfo
UserC
如果表和过程的所有者相同,则不检查表的权限。这称为所有权链接。
注意,在此上下文中,“所有权”是指“模式所有者”。例如,该表TestDB.Schema1.Table1由拥有的用户拥有Schema1。
TestDB.Schema1.Table1
Schema1
因为与Orders具有相同的所有者GetCustomerOrderInfo,所以存储过程具有隐式的读取权限Orders。
但是Customers拥有者不同,因此您必须明确授予对此的权限。
这是一个测试脚本来演示该问题:
use Test go if exists (select * from sys.syslogins where name = 'UserA') drop login UserA create login UserA with password = 'Welcome' if exists (select * from sys.syslogins where name = 'UserB') drop login UserB create login UserB with password = 'Welcome' if exists (select * from sys.syslogins where name = 'UserC') drop login UserC create login UserC with password = 'Welcome' if exists (select * from sys.tables where name = 'Customers' and schema_name(schema_id) = 'SchemaA') drop table SchemaA.Customers if exists (select * from sys.schemas where name = 'SchemaA') drop schema SchemaA if exists (select * from sys.sysusers where name = 'UserA') drop user UserA if exists (select * from sys.tables where name = 'Orders' and schema_name(schema_id) = 'SchemaB') drop table SchemaB.Orders if exists (select * from sys.procedures where name = 'GetCustomerOrderInfo' and schema_name(schema_id) = 'SchemaB') drop procedure SchemaB.GetCustomerOrderInfo if exists (select * from sys.schemas where name = 'SchemaB') drop schema SchemaB if exists (select * from sys.sysusers where name = 'UserB') drop user UserB if exists (select * from sys.sysusers where name = 'UserC') drop user UserC create user UserA for login UserA alter role db_owner add member UserA go create schema SchemaA authorization UserA go create user UserB for login UserB alter role db_owner add member UserB go create schema SchemaB authorization UserB go create user UserC for login UserC create table SchemaA.Customers (id int identity) create table SchemaB.Orders (id int identity, CustomerId int) go create procedure SchemaB.GetCustomerOrderInfo as select * from SchemaB.Orders o join SchemaA.Customers c on c.id = o.CustomerId go
设置完毕后,我们可以使用不同的权限测试该过程。首先,我们需要对存储过程具有执行权限,然后在上具有读取权限Customers。此后,即使我们没有授予对的读取访问权限,该存储过程仍然有效Orders。
execute as login = 'UserC' -- Login as UserC exec SchemaB.GetCustomerOrderInfo -- The EXECUTE permission was denied on the object 'GetCustomerOrderInfo', database 'Test', schema 'SchemaB' revert -- Revert back to our original login grant execute on SchemaB.GetCustomerOrderInfo to UserC execute as login = 'UserC' exec SchemaB.GetCustomerOrderInfo -- The SELECT permission was denied on the object 'Customers', database 'Test', schema 'SchemaA'. revert grant select on SchemaA.Customers to UserC execute as login = 'UserC' exec SchemaB.GetCustomerOrderInfo -- (0 row(s) affected) revert