这是上下文。
我希望user1只能通过sp1修改database2。我不希望user1能够运行:exec database2..sp2
。
以下是我尝试的一些代码:
USE [database2];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
CREATE PROCEDURE [dbo].[sp2]
WITH
EXEC AS CALLER AS
SELECT current_user
GO
GRANT EXECUTE ON [dbo].[sp2] TO [user2]
GO
在database1中我跑了:
use database1
go
drop procedure sp1
go
create procedure sp1
as
declare @m nvarchar(4000)
select current_user as usr
execute as login='user2'
begin try
execute database2.dbo.sp2
end try
begin catch
set @m = error_message()
print @m
revert
end catch
go
grant execute on dbo.sp1 to user1
go
execute as login='user1'
go
execute dbo.sp1
go
revert
go
不幸的是,这个(即login ='user1'上下文中的exec dbo.sp1
)不起作用,它返回:
无法作为服务器主体执行,因为主体“user2”不存在,此类主体不能被模拟,或者您没有权限
我还尝试使用with execute as 'user2'
编译sp1,但是,它不起作用。
还有其他方法可以让我的工作吗?
由于
更新
如果我这样做:
GRANT IMPERSONATE ON User::user2 to [User1];
GO
然后脚本工作,但这意味着User1现在可以执行Database2..sp2。
我想要的是这样的:grant impersonate on User::user2 to [sp1]
,即授予对程序的模仿许可,但我不确定是否可能。
我发现这个thread我认为这也与我的案例有关。
答案 0 :(得分:0)
好的,根据我提到的thread,这是可能的。
以下是实现此目的的脚本:
use database1
go
CREATE CERTIFICATE [PermissionsCert]
AUTHORIZATION [dbo]
ENCRYPTION BY PASSWORD = 'WeakPassword'
WITH SUBJECT = 'Used to test granting permissions to code',
EXPIRY_DATE = '2099-12-31';
ADD SIGNATURE TO [dbo].[sp1]
BY CERTIFICATE [PermissionsCert]
WITH PASSWORD = 'WeakPassword';
BACKUP CERTIFICATE [PermissionsCert] TO FILE = 'k:\Sql_Backup\PermissionsCert.cer'
use database2
go
CREATE CERTIFICATE PermissionsCert
FROM FILE = 'k:\Sql_Backup\PermissionsCert.cer'
CREATE USER [PermissionsUser] FROM CERTIFICATE [PermissionsCert];
grant execute on dbo.sp2 to [PermissionsUser]
go
我修改了sp1如下:
alter procedure sp1
as
declare @m nvarchar(4000)
select current_user as usr
--execute as user='user2'
begin try
execute Database2.dbo.sp2
end try
begin catch
set @m = error_message()
print @m
revert
end catch
go
现在可以使用:
execute as login='user1'
go
execute dbo.sp1
go
revert
go
然而,这失败了,这就是我想要的:
execute as login='user1'
go
execute database2.dbo.sp2
go
revert
go