博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SQL Server使用证书最小粒度授权

Posted on 2017-06-23 11:02  冲杀  阅读(486)  评论(0编辑  收藏  举报

最近在项目中某个功能遇到了阻塞造成的Time out错误。所以需要在执行该功能的时候开启一个线程检测SQL Server中阻塞会话。但是程序本身使用的sql帐号本身不具备VIEW Sever State权限。这个权限是sys_admin角色的。所以就需要使用证书将View Server State权限赋予给普通账号。

在开发之前找到了以下两篇博文参考:

SQL Server 2005: 存储过程签名 - stswordman - 博客园
http://www.cnblogs.com/stswordman/archive/2008/07/29/1255322.html

这一篇使用了master key. 当数据库备份后, 在其他数据库还原时需要master key.

Pitching Pebbles - Using Certificates to Grant Privileges | ColleenMorrow.com
http://colleenmorrow.com/2011/12/19/tossing-pebbles-using-certificates-to-grant-privileges/

这一篇直接使用的证书的密钥做. 没有前一篇master key带来的问题. 只是示例使用的是master库.以及直接赋予的sys_admin角色的权限.

 

本人结合两篇博文的要点,采用证书密码的方式授予View Server State权限。

 

以下是代码

新建一个查看阻塞进程的存储过程:

USE [TestDB]
GO

CREATE PROC [dbo].[sp_CheckBlockSession]
AS
WITH    CTE_SID ( BSID, SID, sql_handle )
          AS ( SELECT   blocking_session_id ,
                        session_id ,
                        sql_handle
               FROM     sys.dm_exec_requests
               WHERE    blocking_session_id <> 0
               UNION ALL
               SELECT   A.blocking_session_id ,
                        A.session_id ,
                        A.sql_handle
               FROM     sys.dm_exec_requests A
                        JOIN CTE_SID B ON A.SESSION_ID = B.BSID
             )
    SELECT  C.BSID AS blocking_session_id,
            C.SID AS session_id,
            S.login_name ,
            S.host_name ,
            S.status ,
            S.cpu_time ,
            S.memory_usage ,
            S.last_request_start_time ,
            S.last_request_end_time ,
            S.logical_reads ,
            S.row_count ,
            q.text
    FROM    CTE_SID C 
            JOIN sys.dm_exec_sessions S ON C.sid = s.session_id
            CROSS APPLY sys.dm_exec_sql_text(C.sql_handle) Q
    ORDER BY sid


新建一个最小权限账户

USE TestDB
GO
--新建一个最小权限账户
CREATE LOGIN TEST_View WITH PASSWORD = '123';
CREATE USER TEST_View FOR LOGIN Test_View
--让该账户有权限执行存储过程dbo.sp_CheckBlockSession
GRANT EXECUTE ON sp_CheckBlockSession TO Test_View

测试最小权限账户执行sp_CheckBlockSession

EXECUTE AS LOGIN = 'TEST_View' ;
EXEC sp_CheckBlockSession 
REVERT ;
 --错误消息
 消息 297,级别 16,状态 1,过程 sp_CheckBlockSession,第 3 行
用户没有执行此操作的权限。

 

USE TestDB
GO
--创建证书以及授权
CREATE CERTIFICATE certSignCheckBlockSession_1 ENCRYPTION BY PASSWORD ='TEST111' WITH SUBJECT = 'for signing procedure sp_CheckBlockSession', EXPIRY_DATE='2025-10-10' ;
-- sp_CheckBlockSession
ADD SIGNATURE TO sp_CheckBlockSession BY CERTIFICATE certSignCheckBlockSession_1 WITH PASSWORD = 'TEST111' ;
BACKUP CERTIFICATE certSignCheckBlockSession_1 TO FILE = 'certSignCheckBlockSession_1.cer' ;

USE master
GO
CREATE CERTIFICATE certSignCheckBlockSession_1 FROM FILE = 'certSignCheckBlockSession_1.cer' ;
 
-- 创建登录并映射到证书
CREATE LOGIN L_TESTVIEW FROM CERTIFICATE certSignCheckBlockSession_1 ;
 -- 通过授权映射登录的方式将ALTER ANY LOGIN权限赋给证书
GRANT VIEW SERVER STATE TO L_TESTVIEW ;

 

--测试最小权限账户权限
USE TestDB
GO
EXECUTE AS LOGIN = 'TEST_View' ;
EXEC sp_CheckBlockSession 
REVERT ;--成功得到结果, 不再提示用户没有此操作权限.

以上是使用证书签名存储过程的全部过程. 可以实现最小粒度权限的赋予。这样在生产环境中,就避免了赋予不必要的管理权限。降低风险!

 注意事项:证书备份路径的问题. 如果没有指定绝对路径。则备份文件在D:\Program Files (x86)\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA(楼主的机器)目录下面。这个目录有可能权限不足而无法备份到里面。本来我想使用绝对路径的。但是由于我开发某个项目时,使用了一个功能造成我当前账户的权限被缩小到很小。无法使用绝对路径进行备份,所以才使用了默认路径。各位做测试的话要注意这个问题。