必要なのは、手続きに署名することです。
M.Ali がコメントで提供したリンクからセットアップを借りましょう (ストアド プロシージャおよび基になるテーブルに対する SQL Server ユーザー権限 ):
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
これがセットアップでした。Andomar に感謝します。
UserC にプロシージャの実行権限を与えることができます:
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
これでは十分ではありませんでした。私たちができることは、データベースに証明書を作成し、この証明書のデータベース ユーザーを作成し、そのユーザーに適切なアクセス許可 (このサンプルでは db_owner ロール) を付与し、証明書を使用して手順に署名することです:
create certificate cert_raiser
encryption by password = 'pGFD4bb925DGvbd2439587y'
with subject = 'raiser',
expiry_date = '01/01/2114';
go
create user cert_user from certificate cert_raiser
go
alter role db_owner add member cert_user
go
add signature to SchemaB.GetCustomerOrderInfo
by certificate cert_raiser
with password = 'pGFD4bb925DGvbd2439587y';
go
これで問題なく動作するはずです。
注意点:証明書で作成されたユーザーは通常のユーザーとして使用できません。このユーザーでのログインはなく、セキュリティ上の問題ではありません。そのユーザーに付与するすべての権限は、署名を追加するときにプロシージャが実行されるコンテキストに追加されます。手順を変更する場合は、再度署名する必要があります。