2

以下の正しい答えは何でしょう?私はEXECUTE権限で十分だと思っていたでしょうか?? ありがとう!

データベースには、所有者という名前のCustomersテーブルと、所有者というUserA名前の別のテーブルがあります。が所有するストアド プロシージャもあります。両方のテーブルからデータを選択します。新しいユーザーを作成します。がストアド プロシージャを呼び出せることを確認する必要があります。また、必要最小限のアクセス許可のみを割り当てる必要があります。OrdersUserBGetCustomerOrderInfoUserBGetCustomerOrderInfoUserCUserCGetCustomerOrderInfoUserC

4

2 に答える 2

9

テーブルとプロシージャの所有者が同じ場合、テーブルに対する権限はチェックされません。これは所有権の連鎖と呼ばれます。

このコンテキストでの「所有権」は「スキーマの所有者」を意味することに注意してください。たとえば、テーブル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
于 2013-10-22T12:22:49.920 に答える