使用证书签名存储过程:调用者判断模块签名状态的最低权限要求
存储过程签名检测的权限要求与实现方案
核心问题
我正在用证书给存储过程签名,需要明确两个点:
- 当存储过程以**调用者身份(WITH EXECUTE AS CALLER)**运行时,判断当前模块是否已签名的最低权限要求是什么?
- 如果模块未签名,如何快速抛出错误并退出存储过程?
问题补充说明
用代码表述的话,低权限用户执行以下查询会返回空结果集,而高权限用户能看到完整的签名信息:
execute as user='lowprivilege' select * from sys.crypt_properties revert;
示例存储过程(需以调用者身份执行)
以下是一个查询已签名对象的存储过程,已指定WITH EXECUTE AS CALLER确保以调用者身份运行:
if object_id('dbo.usp_signedObject') is null begin exec('create procedure dbo.usp_signedObject as ') end go alter procedure [dbo].[usp_signedObject] WITH EXECUTE AS CALLER as begin set nocount on; select [schema] = tblSS.[name] , [object] = tblSO.[name] , [objectType] = tblSO.[type] , [objectTypeDescription] = tblSO.[type_desc] , tblSCP.crypt_type , tblSCP.crypt_type_desc , [certificate] = tblSC.[name] from sys.objects tblSO INNER JOIN sys.schemas tblSS on tblSO.schema_id = tblSS.schema_id INNER JOIN sys.crypt_properties tblSCP on tblSO.[object_id] = tblSCP.major_id and tblSCP.class = 1 LEFT OUTER JOIN sys.certificates tblSC ON tblSC.thumbprint = tblSCP.thumbprint end go grant execute on dbo.usp_signedObject to [public] go
解决方案
1. 检测签名的最低权限要求
要让调用者能查看当前存储过程的签名信息,最低权限是给调用者授予该存储过程的VIEW DEFINITION权限。如果仅需要检测当前运行的存储过程是否已签名,无需查看所有签名对象,只需针对目标存储过程授予这个权限即可,符合最小权限原则。
若授予服务器级的VIEW ANY DEFINITION权限,调用者会能查看所有对象的定义和签名信息,范围过大,不推荐。
2. 未签名时抛出错误并退出
修改存储过程,加入针对当前模块的签名检测逻辑,无签名记录时直接抛出错误终止执行:
alter procedure [dbo].[usp_signedObject] WITH EXECUTE AS CALLER as begin set nocount on; -- 检测当前存储过程是否已签名 if not exists ( select 1 from sys.crypt_properties cp where cp.major_id = @@PROCID and cp.class = 1 -- 类1代表对象(存储过程、函数等) ) begin -- 抛出错误并退出 raiserror('当前存储过程未通过证书签名,无法执行。', 16, 1); return; end -- 原查询逻辑 select [schema] = tblSS.[name] , [object] = tblSO.[name] , [objectType] = tblSO.[type] , [objectTypeDescription] = tblSO.[type_desc] , tblSCP.crypt_type , tblSCP.crypt_type_desc , [certificate] = tblSC.[name] from sys.objects tblSO INNER JOIN sys.schemas tblSS on tblSO.schema_id = tblSS.schema_id INNER JOIN sys.crypt_properties tblSCP on tblSO.[object_id] = tblSCP.major_id and tblSCP.class = 1 LEFT OUTER JOIN sys.certificates tblSC ON tblSC.thumbprint = tblSCP.thumbprint end go
权限授予示例
给低权限用户授予必要的执行和查看定义权限:
grant execute on dbo.usp_signedObject to [lowprivilege]; grant view definition on dbo.usp_signedObject to [lowprivilege];
这样用户既能执行存储过程,又能在过程内部检测当前过程的签名状态,同时无法查看其他对象的签名信息。
内容的提问来源于stack exchange,提问作者Daniel Adeniji
相关产品推荐
相关产品推荐

