限制执行存储过程的权限

时间:2018-04-27 16:33:04

标签: sql-server-2008 sql-server-2008-r2

这是上下文。

  • 两个数据库,database1和database2。
  • 使用用户user1(SQL Server身份验证)访问database1的asp.net Web应用程序。
  • database1中的存储过程sp1,需要通过database2中定义的存储过程sp2修改database2中的某些敏感数据。换句话说,sp1调用database2..sp2。
  • 我创建了一个SQL Server user2登录名,该登录名映射到database1和user2 database2中的user2。 database2中的user2具有执行sp2的权限。

我希望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我认为这也与我的案例有关。

1 个答案:

答案 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