Skip to content

SQLServer 用户与权限管理

权限管理概述

用户与权限管理是 SQL Server 安全管理的核心,通过合理的身份验证、用户管理和权限分配,可以保护数据库资源免受未授权访问和滥用。SQL Server 提供了完善的身份验证和授权机制,支持 Windows 身份验证和 SQL Server 身份验证两种模式,并在不同版本中不断增强安全性功能。

版本差异支持

SQL Server 版本用户权限管理主要变化
2008 R2基础权限管理,支持固定角色和自定义角色
2012引入用户定义服务器角色,增强服务器级权限控制
2016增强动态数据屏蔽和行级安全,支持更细粒度的权限控制
2019引入大数据集群权限,增强混合云场景支持
2022增强 Azure AD 集成,支持云原生身份管理和零信任安全

身份验证模式

Windows 身份验证

核心特点

  • 使用 Windows 操作系统的用户和组进行身份验证
  • 支持 Kerberos 身份验证协议,安全性更高
  • 支持 Windows 组管理,简化权限管理
  • 推荐生产环境使用

配置方法

  1. 在 SQL Server 安装时选择 "Windows 身份验证模式"
  2. 或通过 SQL Server 配置管理器修改身份验证模式:
    • 打开 SQL Server 配置管理器
    • 右键点击 SQL Server 服务,选择 "属性"
    • 在 "安全性" 选项卡中选择 "Windows 身份验证模式"
    • 重启 SQL Server 服务

SQL Server 身份验证

核心特点

  • 使用 SQL Server 内置的用户名和密码进行身份验证
  • 适用于非 Windows 客户端或无法使用 Windows 身份验证的场景
  • 安全性相对较低,需要强密码策略
  • 支持混合身份验证模式

配置方法

  1. 在 SQL Server 安装时选择 "混合身份验证模式"
  2. 或通过 SQL Server 配置管理器修改身份验证模式
  3. 启用 "sa" 账户(如果需要)
  4. 配置强密码策略

登录名与用户管理

登录名 (Login)

登录名是用于连接到 SQL Server 实例的身份,存储在 master 数据库中。

创建 Windows 登录名

sql
-- 创建 Windows 用户登录名
CREATE LOGIN [DOMAIN\Username] FROM WINDOWS;

-- 创建 Windows 组登录名(推荐,便于集中管理)
CREATE LOGIN [DOMAIN\DBUsers] FROM WINDOWS;

创建 SQL Server 登录名

sql
-- 创建带强密码策略的 SQL 登录名
CREATE LOGIN [AppLogin] 
WITH PASSWORD = 'StrongPass123!',
     DEFAULT_DATABASE = [ProductionDB],
     CHECK_EXPIRATION = ON,
     CHECK_POLICY = ON;

-- 创建服务账户登录名(禁用密码过期)
CREATE LOGIN [ServiceLogin] 
WITH PASSWORD = 'ServicePass123!',
     DEFAULT_DATABASE = [ProductionDB],
     CHECK_EXPIRATION = OFF,
     CHECK_POLICY = ON;

登录名管理

sql
-- 修改登录名密码
ALTER LOGIN [AppLogin] WITH PASSWORD = 'NewStrongPass456!';

-- 启用/禁用登录名
ALTER LOGIN [AppLogin] ENABLE;
ALTER LOGIN [AppLogin] DISABLE;

-- 删除登录名
DROP LOGIN [ObsoleteLogin];

用户 (User)

用户是数据库级别的身份,与登录名关联,存储在各个用户数据库中。

创建数据库用户

sql
-- 为 Windows 登录名创建数据库用户
USE [ProductionDB];
CREATE USER [DomainUser] FOR LOGIN [DOMAIN\Username];

-- 为 Windows 组创建数据库用户(推荐)
USE [ProductionDB];
CREATE USER [DBUsers] FOR LOGIN [DOMAIN\DBUsers];

-- 为 SQL 登录名创建带默认架构的数据库用户
USE [ProductionDB];
CREATE USER [AppUser] FOR LOGIN [AppLogin] WITH DEFAULT_SCHEMA = [dbo];

用户管理

sql
-- 修改用户默认架构
USE [ProductionDB];
ALTER USER [AppUser] WITH DEFAULT_SCHEMA = [Sales];

-- 重命名用户
USE [ProductionDB];
ALTER USER [OldUser] WITH NAME = [NewUser];

-- 删除用户
USE [ProductionDB];
DROP USER [ObsoleteUser];

权限分配与管理

权限类型

权限级别作用范围示例权限
服务器级权限整个 SQL Server 实例CREATE ENDPOINT, ALTER ANY LOGIN
数据库级权限单个数据库CREATE TABLE, SELECT, INSERT
对象级权限特定数据库对象SELECT ON table, EXECUTE ON procedure

授予权限

服务器级权限

sql
-- 授予服务器级权限
GRANT ALTER ANY LOGIN TO [SecurityAdminLogin];

数据库级权限

sql
-- 授予数据库级权限
USE [ProductionDB];
GRANT CREATE TABLE, CREATE VIEW TO [DBAdminUser];

对象级权限

sql
-- 授予表权限
USE [ProductionDB];
GRANT SELECT, INSERT, UPDATE ON [Sales].[Orders] TO [SalesUser];

-- 授予存储过程执行权限
USE [ProductionDB];
GRANT EXECUTE ON [Sales].[usp_ProcessOrder] TO [AppUser];

-- 授予架构权限
USE [ProductionDB];
GRANT SELECT ON SCHEMA::[Sales] TO [ReadOnlyUser];

权限拒绝与撤销

sql
-- 拒绝权限(优先于授予权限)
USE [ProductionDB];
DENY DELETE ON [Sales].[Orders] TO [SalesUser];

-- 撤销权限
USE [ProductionDB];
REVOKE INSERT ON [Sales].[Orders] TO [SalesUser];

角色管理

角色管理是权限管理的重要组成部分,通过角色可以将一组权限分配给多个用户,简化权限管理并提高安全性。

固定服务器角色

固定服务器角色是 SQL Server 内置的服务器级角色,具有预定义的服务器级权限。

角色名称核心权限生产适用场景安全建议
sysadmin实例所有权限核心 DBA 团队严格控制成员数量
serveradmin服务器配置与关闭高级系统管理员限制使用
securityadmin登录名与服务器权限管理安全管理员与其他角色职责分离
processadmin终止 SQL 进程故障排查紧急情况使用
setupadmin链接服务器管理集成场景限制使用
bulkadminBULK INSERT 操作数据加载按需分配
diskadmin数据库文件管理存储管理限制使用
dbcreator数据库创建与修改开发环境生产环境谨慎使用

服务器角色管理

sql
-- 添加成员到服务器角色
ALTER SERVER ROLE [securityadmin] ADD MEMBER [SecurityLogin];

-- 从服务器角色移除成员
ALTER SERVER ROLE [sysadmin] DROP MEMBER [LeavingDba];

固定数据库角色

固定数据库角色是 SQL Server 内置的数据库级角色,具有预定义的数据库级权限。

角色名称核心权限生产适用场景
db_owner数据库所有权限数据库所有者
db_securityadmin数据库角色与权限管理数据库安全管理员
db_accessadmin数据库用户与权限管理数据库访问管理员
db_backupoperator数据库备份操作备份操作员
db_ddladminDDL 操作架构管理员
db_datawriter数据写入操作数据录入人员
db_datareader数据读取操作报表用户

数据库角色管理

sql
-- 添加成员到数据库角色
USE [ProductionDB];
ALTER ROLE [db_datareader] ADD MEMBER [ReadOnlyUser];

-- 从数据库角色移除成员
USE [ProductionDB];
ALTER ROLE [db_owner] DROP MEMBER [AppUser];

自定义角色

对于复杂的权限管理,可以创建自定义角色,根据业务需求分配特定权限。

sql
-- 创建销售只读角色
USE [ProductionDB];
CREATE ROLE [SalesReadOnly];

-- 分配权限
GRANT SELECT ON [Sales].[Orders] TO [SalesReadOnly];
GRANT SELECT ON [Sales].[Customers] TO [SalesReadOnly];

-- 创建销售数据录入角色
USE [ProductionDB];
CREATE ROLE [SalesDataEntry];

-- 分配权限
GRANT SELECT, INSERT, UPDATE ON [Sales].[Orders] TO [SalesDataEntry];
GRANT EXECUTE ON [Sales].[usp_ProcessOrder] TO [SalesDataEntry];

-- 添加用户到自定义角色
ALTER ROLE [SalesReadOnly] ADD MEMBER [SalesUser1];
ALTER ROLE [SalesDataEntry] ADD MEMBER [SalesUser2];

生产场景最佳实践

1. 权限管理实施流程

步骤1:需求分析

  • 识别业务功能和数据访问需求
  • 定义角色和权限矩阵
  • 确定权限边界

步骤2:角色设计

  • 基于业务功能设计角色
  • 遵循最小权限原则
  • 避免角色数量过多

步骤3:权限分配

  • 优先使用角色而非直接分配权限
  • 定期审查权限分配
  • 记录权限变更

步骤4:测试与验证

  • 测试角色权限是否符合预期
  • 验证权限边界
  • 模拟各种访问场景

步骤5:监控与审计

  • 启用权限审计
  • 监控异常访问
  • 定期生成权限报告

2. 不同环境的权限策略

环境类型权限策略实施建议
开发环境相对宽松允许开发人员使用 db_ddladmin 角色
测试环境接近生产限制 sysadmin 和 db_owner 角色
生产环境严格控制仅核心 DBA 拥有 sysadmin 权限
灾备环境与生产一致权限配置与生产环境同步

3. 权限审计与监控

服务器级权限审计

sql
-- 创建服务器级触发器,审计登录名和权限变更
CREATE TRIGGER tr_server_permission_audit
ON ALL SERVER
FOR CREATE_LOGIN, ALTER_LOGIN, DROP_LOGIN, 
    ADD_SERVER_ROLE_MEMBER, DROP_SERVER_ROLE_MEMBER,
    GRANT_SERVER, DENY_SERVER, REVOKE_SERVER
AS
BEGIN
    SET NOCOUNT ON;
    
    DECLARE @event_data XML = EVENTDATA();
    INSERT INTO [DBA].[dbo].[ServerPermissionAudit] (
        EventTime, EventType, EventData, ChangedBy
    )
    VALUES (
        GETDATE(), @event_data.value('(/EVENT_INSTANCE/EventType)[1]', 'VARCHAR(50)'),
        @event_data, ORIGINAL_LOGIN()
    );
END;

数据库级权限审计

sql
-- 创建数据库级触发器,审计用户和权限变更
USE [ProductionDB];
CREATE TRIGGER tr_db_permission_audit
ON DATABASE
FOR CREATE_USER, ALTER_USER, DROP_USER,
    ADD_ROLE_MEMBER, DROP_ROLE_MEMBER,
    GRANT, DENY, REVOKE
AS
BEGIN
    SET NOCOUNT ON;
    
    DECLARE @event_data XML = EVENTDATA();
    INSERT INTO [dbo].[DbPermissionAudit] (
        EventTime, EventType, EventData, ChangedBy
    )
    VALUES (
        GETDATE(), @event_data.value('(/EVENT_INSTANCE/EventType)[1]', 'VARCHAR(50)'),
        @event_data, ORIGINAL_LOGIN()
    );
END;

4. 权限报告生成

sql
-- 生成登录名权限报告
SELECT 
    sp.name AS login_name,
    sp.type_desc AS login_type,
    sr.name AS server_role
FROM sys.server_role_members srm
JOIN sys.server_principals sp ON srm.member_principal_id = sp.principal_id
JOIN sys.server_principals sr ON srm.role_principal_id = sr.principal_id
ORDER BY sp.name;

-- 生成数据库用户权限报告
USE [ProductionDB];
SELECT 
    dp.name AS user_name,
    dp.type_desc AS user_type,
    dr.name AS database_role
FROM sys.database_role_members drm
JOIN sys.database_principals dp ON drm.member_principal_id = dp.principal_id
JOIN sys.database_principals dr ON drm.role_principal_id = dr.principal_id
ORDER BY dp.name;

-- 生成对象级权限报告
USE [ProductionDB];
SELECT 
    dp.name AS grantee,
    OBJECT_NAME(dpr.major_id) AS object_name,
    dpr.permission_name,
    dpr.state_desc
FROM sys.database_permissions dpr
JOIN sys.database_principals dp ON dpr.grantee_principal_id = dp.principal_id
WHERE dpr.major_id > 0 -- 排除系统对象
ORDER BY dp.name, object_name;

常见问题 (FAQ)

如何查看某个用户的所有权限?

sql
-- 查看登录名的服务器级权限
EXECUTE AS LOGIN = 'LoginName';
SELECT * FROM fn_my_permissions(NULL, 'SERVER');
REVERT;

-- 查看用户的数据库级权限
USE DatabaseName;
EXECUTE AS USER = 'UserName';
SELECT * FROM fn_my_permissions(NULL, 'DATABASE');
REVERT;

-- 查看用户对特定表的权限
USE DatabaseName;
EXECUTE AS USER = 'UserName';
SELECT * FROM fn_my_permissions('SchemaName.TableName', 'OBJECT');
REVERT;

如何实现权限的定期审查?

  1. 制定审查计划:每季度或每半年进行一次权限审查
  2. 生成权限报告:使用上述脚本生成详细的权限报告
  3. 业务部门确认:与业务部门确认用户权限需求
  4. 权限调整:移除不必要的权限,调整权限分配
  5. 记录变更:记录审查结果和权限变更
  6. 持续监控:配置权限变更告警,实时监控权限变化

如何处理离职员工的权限?

  1. 立即禁用账户:禁用离职员工的 Windows 账户或 SQL 登录名
  2. 移除角色成员资格:从所有角色中移除该用户
  3. 撤销直接权限:撤销该用户的所有直接权限
  4. 审查相关权限:检查是否有其他用户共享了相同的权限
  5. 记录变更:记录权限变更的原因和时间

如何管理大量用户的权限?

  1. 使用 Windows 组:将用户添加到 Windows 组,然后为组分配权限
  2. 使用角色管理:创建基于业务功能的角色,将用户添加到对应角色
  3. 自动化管理:使用 PowerShell 脚本或第三方工具自动化权限管理
  4. 定期同步:与 HR 系统或 Active Directory 定期同步用户信息
  5. 批量操作:使用批量脚本处理大量用户的权限变更

如何选择合适的身份验证模式?

场景推荐身份验证模式原因
企业内部应用Windows 身份验证更安全,便于集中管理
外部应用访问SQL Server 身份验证适用于非 Windows 客户端
混合云环境Azure AD 身份验证(SQL Server 2022+)云原生身份管理,支持 SSO
开发测试环境混合身份验证灵活性高,便于测试

如何安全使用 "sa" 账户?

  1. 禁用 "sa" 账户:除非必要,否则禁用 "sa" 账户
  2. 重命名 "sa" 账户:如果必须使用,建议重命名 "sa" 账户
  3. 强密码策略:为 "sa" 账户设置强密码
  4. 限制登录 IP:通过登录触发器限制 "sa" 账户的登录 IP
  5. 监控 "sa" 登录:启用 "sa" 账户登录审计,监控异常登录

如何实现跨数据库的权限管理?

  1. 使用相同的角色名称:在多个数据库中创建同名角色,分配相似权限
  2. 使用包含数据库:包含数据库中的用户可以访问其他包含数据库
  3. 使用应用程序角色:在应用程序中管理跨数据库访问
  4. 使用数据库链接:通过数据库链接实现跨数据库访问,并配置适当权限
  5. 使用 Azure SQL 托管实例:托管实例支持跨数据库查询,简化权限管理

总结

用户与权限管理是 SQL Server 安全管理的核心,通过合理的身份验证配置、用户管理、权限分配和角色设计,可以构建安全、高效的权限管理体系。不同版本的 SQL Server 在用户权限管理方面不断增强,特别是在高版本中支持更细粒度的权限控制和云原生身份管理。

在实际生产环境中,建议遵循以下核心原则:

  1. 最小权限原则:只为用户分配完成任务所需的最小权限
  2. 角色管理优先:使用角色而非直接分配权限,简化权限管理
  3. 定期审查与审计:定期审查用户权限,启用权限审计和监控
  4. 强密码策略:对 SQL 登录名启用强密码策略
  5. 职责分离:分离不同角色的职责,避免权限集中
  6. 版本特性利用:充分利用不同 SQL Server 版本的权限管理特性

通过实施这些最佳实践,可以保护 SQL Server 数据库资源免受未授权访问和滥用,确保企业数据资产的安全。