You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

查询Microsoft SQL Server数据库角色权限变更历史的方法

SQL Server数据库角色权限变更历史查询方案

默认情况下,SQL Server的系统视图仅存储当前生效的权限状态,不保留权限变更的历史记录(包括变更时间、操作人)。要获取这类历史信息,需依赖日志审计或专门的监控配置,以下是可行方案:

一、通过事务日志回溯历史(无提前配置时的应急方案)

如果数据库采用完整恢复模式且事务日志未被备份截断,可以通过系统函数fn_dblog解析日志,提取角色权限的GRANT/REVOKE/DENY操作记录。

查询语句示例:

SELECT
    -- 解析目标角色名称
    SUBSTRING(OperationDescription, CHARINDEX('TO ', OperationDescription) + 3, LEN(OperationDescription) - CHARINDEX('TO ', OperationDescription) - 2) AS [Role],
    -- 解析具体权限内容
    CASE
        WHEN OperationDescription LIKE 'GRANT%' THEN SUBSTRING(OperationDescription, CHARINDEX('GRANT ', OperationDescription) + 6, CHARINDEX(' TO ', OperationDescription) - CHARINDEX('GRANT ', OperationDescription) - 6)
        WHEN OperationDescription LIKE 'REVOKE%' THEN SUBSTRING(OperationDescription, CHARINDEX('REVOKE ', OperationDescription) + 7, CHARINDEX(' TO ', OperationDescription) - CHARINDEX('REVOKE ', OperationDescription) - 7)
        WHEN OperationDescription LIKE 'DENY%' THEN SUBSTRING(OperationDescription, CHARINDEX('DENY ', OperationDescription) + 5, CHARINDEX(' TO ', OperationDescription) - CHARINDEX('DENY ', OperationDescription) - 5)
    END AS [Permission],
    -- 变更时间
    [TransactionTime] AS [Modify_Date],
    -- 操作人账号
    s.login_name AS [Grantor Name],
    -- 操作类型说明
    CASE 
        WHEN OperationDescription LIKE 'GRANT%' THEN '(授予权限)' 
        WHEN OperationDescription LIKE 'REVOKE%' THEN '(撤销权限)' 
        WHEN OperationDescription LIKE 'DENY%' THEN '(拒绝权限)' 
    END AS [Operation]
FROM
    fn_dblog(NULL, NULL) d
JOIN
    sys.dm_tran_session_transactions st ON d.transaction_id = st.transaction_id
JOIN
    sys.dm_exec_sessions s ON st.session_id = s.session_id
WHERE
    d.Operation IN ('LOP_GRANT_PERM', 'LOP_REVOKE_PERM', 'LOP_DENY_PERM')
    AND OperationDescription LIKE '%TO %' -- 过滤针对角色/用户的权限操作
ORDER BY
    TransactionTime DESC;

注意事项:

  • 仅适用于完整恢复模式,且事务日志未被自动截断或备份覆盖;
  • 日志解析的字符串逻辑需根据实际权限语句调整,部分复杂权限可能解析不准确;
  • 无法获取已被清理的历史日志记录。

二、通过SQL Server Audit持续记录权限变更(推荐方案)

要长期稳定获取权限变更历史,建议配置SQL Server Audit,专门捕获数据库角色的权限操作。

1. 创建审计对象与规范

-- 创建服务器级审计(指定日志存储路径,按需修改)
CREATE SERVER AUDIT [RolePermissionAudit]
TO FILE (FILEPATH = 'D:\SQL_Audit_Logs\', MAXSIZE = 100 MB)
WITH (QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE);

-- 启用审计
ALTER SERVER AUDIT [RolePermissionAudit] WITH (STATE = ON);

-- 创建数据库级审计规范(替换[YourDatabase]为目标库名)
CREATE DATABASE AUDIT SPECIFICATION [RolePermissionAuditSpec]
FOR SERVER AUDIT [RolePermissionAudit]
ADD (GRANT_DATABASE_PERMISSION ON DATABASE::[YourDatabase] TO PUBLIC),
ADD (REVOKE_DATABASE_PERMISSION ON DATABASE::[YourDatabase] TO PUBLIC),
ADD (DENY_DATABASE_PERMISSION ON DATABASE::[YourDatabase] TO PUBLIC)
WITH (STATE = ON);

2. 查询审计日志获取历史记录

SELECT
    target_name AS [Role],
    -- 转换权限操作描述为可读格式
    CASE action_id_desc
        WHEN 'GRANT_DATABASE_PERMISSION' THEN SUBSTRING(additional_information, CHARINDEX('permission_name":"', additional_information)+17, CHARINDEX('"', additional_information, CHARINDEX('permission_name":"', additional_information)+17)-CHARINDEX('permission_name":"', additional_information)-17)
        WHEN 'REVOKE_DATABASE_PERMISSION' THEN SUBSTRING(additional_information, CHARINDEX('permission_name":"', additional_information)+17, CHARINDEX('"', additional_information, CHARINDEX('permission_name":"', additional_information)+17)-CHARINDEX('permission_name":"', additional_information)-17)
        WHEN 'DENY_DATABASE_PERMISSION' THEN SUBSTRING(additional_information, CHARINDEX('permission_name":"', additional_information)+17, CHARINDEX('"', additional_information, CHARINDEX('permission_name":"', additional_information)+17)-CHARINDEX('permission_name":"', additional_information)-17)
    END AS [Permission],
    event_time AS [Modify_Date],
    session_server_principal_name AS [Grantor Name],
    CASE action_id_desc
        WHEN 'GRANT_DATABASE_PERMISSION' THEN '(授予权限)'
        WHEN 'REVOKE_DATABASE_PERMISSION' THEN '(撤销权限)'
        WHEN 'DENY_DATABASE_PERMISSION' THEN '(拒绝权限)'
    END AS [Operation]
FROM
    sys.fn_get_audit_file('D:\SQL_Audit_Logs\RolePermissionAudit_*.sqlaudit', DEFAULT, DEFAULT)
WHERE
    action_id IN ('GDR', 'RVD', 'DND') -- 对应授予/撤销/拒绝数据库权限的操作码
ORDER BY
    event_time DESC;

查询结果示例(匹配需求格式):

RolePermissionModify_DateGrantor NameOperation
publicAlter any certificate2023-08-11 12:07:50.117domain\user(授予权限)
publicAlter any certificate2023-08-11 12:08:00.102domain\user(撤销权限)

三、扩展事件方案(轻量级监控)

若不想使用SQL Server Audit,也可通过扩展事件创建会话,捕获权限变更操作,从事件文件或实时会话中提取记录,适合精细化监控场景。

内容的提问来源于stack exchange,提问作者Jeremy F.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:35:01