1. 首页 > SQLServer教程 > 正文

SQLServer教程FG073-SQLServer角色权限实战

本文档风哥主要介绍SQLServer数据库角色权限管理相关知识,包括SQLServer数据库服务器角色、SQLServer数据库角色、SQLServer数据库权限授予与撤销、SQLServer数据库权限最佳实践等内容,风哥教程参考SQLServer官方文档Security内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

Part01-基础概念与理论知识

1.1 SQLServer数据库角色权限概念

SQLServer数据库角色权限是数据库安全管理的核心机制,通过角色将权限进行分组管理,简化权限分配和维护工作。角色是一组权限的集合,用户通过成为角色的成员来获得相应的权限,实现权限的统一管理和灵活分配。更多视频教程www.fgedu.net.cn

SQLServer数据库角色权限的特点:

  • 权限分组管理,简化授权操作
  • 支持角色嵌套,实现权限继承
  • 灵活的权限组合,满足不同需求
  • 便于权限审计和维护
  • 支持自定义角色,扩展性强

1.2 SQLServer数据库角色类型

# SQLServer数据库服务器角色(固定服务器角色)

sysadmin 系统管理员,拥有所有权限
securityadmin 安全管理员,管理登录和权限
serveradmin 服务器管理员,管理服务器配置
setupadmin 安装管理员,管理链接服务器
processadmin 进程管理员,管理进程
diskadmin 磁盘管理员,管理磁盘文件
dbcreator 数据库创建者,创建和修改数据库
bulkadmin 批量插入管理员,执行批量插入

# SQLServer数据库角色(固定数据库角色)

db_owner 数据库所有者,拥有所有权限
db_accessadmin 访问管理员,管理数据库访问
db_securityadmin 安全管理员,管理数据库权限
db_ddladmin DDL管理员,执行DDL语句
db_backupoperator 备份操作员,执行备份
db_datareader 数据读取者,读取所有表数据
db_datawriter 数据写入者,写入所有表数据
db_denydatareader 拒绝数据读取
db_denydatawriter 拒绝数据写入
public 公共角色,所有用户默认成员

1.3 SQLServer数据库权限层级

SQLServer数据库权限层级结构:

  • 服务器级别权限:控制服务器范围的操作,如创建数据库、管理登录
  • 数据库级别权限:控制数据库范围的操作,如创建表、执行存储过程
  • 架构级别权限:控制架构内对象的访问权限
  • 对象级别权限:控制具体对象的操作权限,如SELECT、INSERT、UPDATE
  • 列级别权限:控制表中特定列的访问权限
# SQLServer数据库权限层级示意

服务器级别(Server-level)
├── CREATE ANY DATABASE
├── ALTER ANY LOGIN
├── CONTROL SERVER
└── VIEW SERVER STATE

数据库级别(Database-level)
├── CREATE TABLE
├── CREATE PROCEDURE
├── ALTER ANY USER
└── BACKUP DATABASE

架构级别(Schema-level)
├── SELECT
├── INSERT
├── UPDATE
└── EXECUTE

对象级别(Object-level)
├── SELECT ON 表名
├── INSERT ON 表名
├── EXECUTE ON 存储过程名
└── REFERENCES ON 表名

风哥提示:理解权限层级结构对于正确配置权限至关重要。建议从高级别到低级别逐层配置权限,避免权限冲突和过度授权。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 SQLServer数据库角色权限规划

SQLServer数据库角色权限规划要点:

# 角色权限规划步骤

1. 识别用户类型
– 数据库管理员(DBA)
– 应用程序账户
– 开发人员
– 业务分析人员
– 只读用户

2. 定义权限需求
– 每种用户类型需要的操作
– 需要访问的对象
– 敏感数据的访问控制

3. 设计角色架构
– 创建自定义角色
– 定义角色权限
– 规划角色层次

4. 实施权限分配
– 创建登录和用户
– 分配角色成员
– 验证权限配置

# 不同用户类型的权限规划

DBA角色:
– 服务器角色: sysadmin 或自定义DBA角色
– 数据库角色: db_owner

应用账户角色:
– 服务器角色: 无或public
– 数据库角色: db_datareader + db_datawriter
– 或自定义应用角色

开发人员角色:
– 服务器角色: 无
– 数据库角色: db_ddladmin(开发环境)
– 生产环境只读权限

只读用户角色:
– 服务器角色: 无
– 数据库角色: db_datareader

2.2 SQLServer数据库角色设计原则

SQLServer数据库角色设计原则:

  • 最小权限原则:只授予完成工作所需的最小权限
  • 职责分离原则:不同职责使用不同角色,避免权限集中
  • 角色复用原则:相同权限需求的用户使用相同角色
  • 权限继承原则:利用角色嵌套实现权限继承
  • 审计友好原则:角色设计便于权限审计和追溯

2.3 SQLServer数据库权限管理策略

# SQLServer数据库权限管理策略

1. 权限申请流程
– 用户提交权限申请
– 审批人审核申请
– DBA执行权限分配
– 记录权限变更

2. 权限定期审查
– 每季度审查用户权限
– 清理不必要的权限
– 更新权限文档

3. 权限变更管理
– 记录所有权限变更
– 保留变更历史
– 支持权限回滚

4. 权限审计
– 监控权限使用情况
– 记录权限变更操作
– 生成权限审计报告

生产环境建议:建立完善的权限管理制度,定期审查权限配置,确保权限分配合理、可追溯。学习交流加群风哥QQ113257174

Part03-生产环境项目实施方案

3.1 SQLServer数据库服务器角色管理

3.1.1 SQLServer数据库查看服务器角色

# 查看所有固定服务器角色
SELECT name, type_desc, is_fixed_role
FROM sys.server_principals
WHERE type = ‘R’
ORDER BY name;
GO

name type_desc is_fixed_role
————— ———– ————-
bulkadmin SERVER_ROLE 1
dbcreator SERVER_ROLE 1
diskadmin SERVER_ROLE 1
processadmin SERVER_ROLE 1
public SERVER_ROLE 1
securityadmin SERVER_ROLE 1
serveradmin SERVER_ROLE 1
setupadmin SERVER_ROLE 1
sysadmin SERVER_ROLE 1

# 查看服务器角色成员
SELECT sp.name AS RoleName, mp.name AS MemberName, mp.type_desc
FROM sys.server_role_members srm
JOIN sys.server_principals sp ON srm.role_principal_id = sp.principal_id
JOIN sys.server_principals mp ON srm.member_principal_id = mp.principal_id
ORDER BY sp.name, mp.name;
GO

RoleName MemberName type_desc
————- ——————– ————-
sysadmin NT AUTHORITY\SYSTEM WINDOWS_LOGIN
sysadmin fgedu_dba SQL_LOGIN
dbcreator fgedu_dev SQL_LOGIN
bulkadmin fgedu_etl SQL_LOGIN

# 查看特定登录的服务器角色
EXEC sp_helpsrvrolemember ‘sysadmin’;
GO

ServerRole MemberName MemberSID
————- ——————– ——————
sysadmin NT AUTHORITY\SYSTEM 0x0101000000000005…
sysadmin fgedu_dba 0x5E2A3B4C5D6E7F8A…

3.1.2 SQLServer数据库创建自定义服务器角色

# 创建自定义服务器角色
CREATE SERVER ROLE fgedu_serveradmin;
GO

Command(s) completed successfully.

# 授予服务器级别权限
GRANT ALTER ANY DATABASE TO fgedu_serveradmin;
GRANT CREATE ANY DATABASE TO fgedu_serveradmin;
GRANT VIEW SERVER STATE TO fgedu_serveradmin;
GO

Command(s) completed successfully.

# 添加成员到服务器角色
ALTER SERVER ROLE fgedu_serveradmin ADD MEMBER fgedu_dba;
GO

Command(s) completed successfully.

# 验证自定义服务器角色
SELECT name, type_desc, is_fixed_role
FROM sys.server_principals
WHERE name = ‘fgedu_serveradmin’;
GO

name type_desc is_fixed_role
——————- ———– ————-
fgedu_serveradmin SERVER_ROLE 0

# 查看自定义服务器角色权限
SELECT permission_name, state_desc
FROM sys.server_permissions
WHERE grantee_principal_id = (
SELECT principal_id FROM sys.server_principals WHERE name = ‘fgedu_serveradmin’
);
GO

permission_name state_desc
———————— ———–
ALTER ANY DATABASE GRANT
CREATE ANY DATABASE GRANT
VIEW SERVER STATE GRANT

3.2 SQLServer数据库角色管理

3.2.1 SQLServer数据库查看数据库角色

# 切换到目标数据库
USE fgedudb;
GO

Changed database context to ‘fgedudb’.

# 查看所有数据库角色
SELECT name, type_desc, is_fixed_role
FROM sys.database_principals
WHERE type = ‘R’
ORDER BY name;
GO

name type_desc is_fixed_role
——————- ————– ————-
db_accessadmin DATABASE_ROLE 1
db_backupoperator DATABASE_ROLE 1
db_datareader DATABASE_ROLE 1
db_datawriter DATABASE_ROLE 1
db_ddladmin DATABASE_ROLE 1
db_denydatareader DATABASE_ROLE 1
db_denydatawriter DATABASE_ROLE 1
db_owner DATABASE_ROLE 1
db_securityadmin DATABASE_ROLE 1
public DATABASE_ROLE 1

# 查看数据库角色成员
SELECT dr.name AS RoleName, dp.name AS MemberName, dp.type_desc
FROM sys.database_role_members drm
JOIN sys.database_principals dr ON drm.role_principal_id = dr.principal_id
JOIN sys.database_principals dp ON drm.member_principal_id = dp.principal_id
ORDER BY dr.name, dp.name;
GO

RoleName MemberName type_desc
————— ———– ————-
db_datareader fgedu_read SQL_USER
db_datareader fgedu_app SQL_USER
db_datawriter fgedu_app SQL_USER
db_owner dbo WINDOWS_USER
db_owner fgedu_dba SQL_USER

3.2.2 SQLServer数据库创建自定义数据库角色

# 创建自定义数据库角色
USE fgedudb;
GO

CREATE ROLE fgedu_app_role;
GO

Command(s) completed successfully.

# 授予架构级别权限
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::dbo TO fgedu_app_role;
GO

Command(s) completed successfully.

# 授予存储过程执行权限
GRANT EXECUTE ON SCHEMA::dbo TO fgedu_app_role;
GO

Command(s) completed successfully.

# 创建只读角色
CREATE ROLE fgedu_readonly_role;
GO

Command(s) completed successfully.

GRANT SELECT ON SCHEMA::dbo TO fgedu_readonly_role;
GO

Command(s) completed successfully.

# 创建报表角色
CREATE ROLE fgedu_report_role;
GO

Command(s) completed successfully.

GRANT SELECT ON SCHEMA::dbo TO fgedu_report_role;
GRANT VIEW DEFINITION ON SCHEMA::dbo TO fgedu_report_role;
GO

Command(s) completed successfully.

# 验证自定义角色
SELECT name, type_desc, is_fixed_role
FROM sys.database_principals
WHERE type = ‘R’ AND is_fixed_role = 0;
GO

name type_desc is_fixed_role
——————- ————– ————-
fgedu_app_role DATABASE_ROLE 0
fgedu_readonly_role DATABASE_ROLE 0
fgedu_report_role DATABASE_ROLE 0

3.3 SQLServer数据库权限授予与撤销

3.3.1 SQLServer数据库权限授予

# 创建数据库用户
USE fgedudb;
GO

CREATE USER fgedu_app FOR LOGIN fgedu_app;
GO

Command(s) completed successfully.

# 添加用户到角色
ALTER ROLE db_datareader ADD MEMBER fgedu_app;
ALTER ROLE db_datawriter ADD MEMBER fgedu_app;
GO

Command(s) completed successfully.

# 授予对象级别权限
GRANT SELECT, INSERT, UPDATE ON fgedu_orders TO fgedu_app;
GO

Command(s) completed successfully.

# 授予列级别权限
GRANT SELECT (order_id, customer_name, order_date) ON fgedu_orders TO fgedu_report;
GO

Command(s) completed successfully.

# 授予存储过程执行权限
GRANT EXECUTE ON fgedu_get_orders TO fgedu_app;
GO

Command(s) completed successfully.

# 授予WITH GRANT OPTION(允许传递权限)
GRANT SELECT ON fgedu_products TO fgedu_lead WITH GRANT OPTION;
GO

Command(s) completed successfully.

# 查看用户权限
SELECT
USER_NAME(grantee_principal_id) AS Grantee,
permission_name,
state_desc,
OBJECT_NAME(major_id) AS ObjectName
FROM sys.database_permissions
WHERE USER_NAME(grantee_principal_id) = ‘fgedu_app’;
GO

Grantee permission_name state_desc ObjectName
——— ————— ———- —————
fgedu_app SELECT GRANT fgedu_orders
fgedu_app INSERT GRANT fgedu_orders
fgedu_app UPDATE GRANT fgedu_orders
fgedu_app EXECUTE GRANT fgedu_get_orders

3.3.2 SQLServer数据库权限撤销

# 撤销对象权限
REVOKE SELECT, INSERT, UPDATE ON fgedu_orders FROM fgedu_app;
GO

Command(s) completed successfully.

# 拒绝权限(DENY优先级最高)
DENY DELETE ON fgedu_orders TO fgedu_app;
GO

Command(s) completed successfully.

# 从角色移除用户
ALTER ROLE db_datawriter DROP MEMBER fgedu_app;
GO

Command(s) completed successfully.

# 撤销架构权限
REVOKE SELECT ON SCHEMA::dbo FROM fgedu_app;
GO

Command(s) completed successfully.

# 撤销WITH GRANT OPTION权限
REVOKE GRANT OPTION FOR SELECT ON fgedu_products FROM fgedu_lead;
GO

Command(s) completed successfully.

# 查看权限变更后的状态
SELECT
USER_NAME(grantee_principal_id) AS Grantee,
permission_name,
state_desc,
OBJECT_NAME(major_id) AS ObjectName
FROM sys.database_permissions
WHERE USER_NAME(grantee_principal_id) = ‘fgedu_app’;
GO

Grantee permission_name state_desc ObjectName
——— ————— ———- —————
fgedu_app DELETE DENY fgedu_orders
fgedu_app EXECUTE GRANT fgedu_get_orders

风哥提示:DENY权限的优先级最高,会覆盖GRANT权限。在权限管理时要特别注意DENY的使用,避免意外阻止用户访问。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 SQLServer数据库应用账户权限配置案例

# 需求:为应用程序配置数据库访问权限
# 应用需要:读取和写入业务表、执行存储过程、不能访问系统表

# 实施步骤:

# 1. 创建登录账户
CREATE LOGIN fgedu_app_user
WITH PASSWORD = ‘Fgedu@App#2026!’,
CHECK_POLICY = ON,
DEFAULT_DATABASE = fgedudb;
GO

Command(s) completed successfully.

# 2. 创建数据库用户
USE fgedudb;
GO

CREATE USER fgedu_app_user FOR LOGIN fgedu_app_user;
GO

Command(s) completed successfully.

# 3. 创建应用角色
CREATE ROLE fgedu_application_role;
GO

Command(s) completed successfully.

# 4. 授予业务表权限
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::business TO fgedu_application_role;
GO

Command(s) completed successfully.

# 5. 授予存储过程执行权限
GRANT EXECUTE ON SCHEMA::dbo TO fgedu_application_role;
GO

Command(s) completed successfully.

# 6. 拒绝系统表访问
DENY SELECT ON SCHEMA::sys TO fgedu_application_role;
GO

Command(s) completed successfully.

# 7. 将用户添加到角色
ALTER ROLE fgedu_application_role ADD MEMBER fgedu_app_user;
GO

Command(s) completed successfully.

# 8. 验证权限配置
EXECUTE AS USER = ‘fgedu_app_user’;
GO

SELECT USER_NAME() AS CurrentUser;
GO

CurrentUser
—————
fgedu_app_user

# 测试表访问
SELECT * FROM business.fgedu_orders;
GO

order_id customer_name order_date total_amount
——– ————- ———– ————
101 张三 2026-04-01 1500.00
102 李四 2026-04-02 2300.00

# 测试系统表访问(应该失败)
SELECT * FROM sys.objects;
GO

Msg 229, Level 14, State 5, Line 1
The SELECT permission was denied on the object ‘objects’, database ‘mssqlsystemresource’, schema ‘sys’.

# 恢复原始用户
REVERT;
GO

Command(s) completed successfully.

4.2 SQLServer数据库只读用户权限配置案例

# 需求:为数据分析人员配置只读访问权限
# 用户需要:查询业务表、查看存储过程定义、不能修改数据

# 实施步骤:

# 1. 创建登录账户
CREATE LOGIN fgedu_readonly
WITH PASSWORD = ‘Fgedu@Read#2026!’,
CHECK_POLICY = ON,
DEFAULT_DATABASE = fgedudb;
GO

Command(s) completed successfully.

# 2. 创建数据库用户
USE fgedudb;
GO

CREATE USER fgedu_readonly FOR LOGIN fgedu_readonly;
GO

Command(s) completed successfully.

# 3. 创建只读角色
CREATE ROLE fgedu_readonly_role;
GO

Command(s) completed successfully.

# 4. 授予SELECT权限
GRANT SELECT ON SCHEMA::business TO fgedu_readonly_role;
GRANT SELECT ON SCHEMA::dbo TO fgedu_readonly_role;
GO

Command(s) completed successfully.

# 5. 授予查看定义权限
GRANT VIEW DEFINITION ON SCHEMA::dbo TO fgedu_readonly_role;
GO

Command(s) completed successfully.

# 6. 拒绝数据修改权限
DENY INSERT, UPDATE, DELETE ON SCHEMA::business TO fgedu_readonly_role;
DENY INSERT, UPDATE, DELETE ON SCHEMA::dbo TO fgedu_readonly_role;
GO

Command(s) completed successfully.

# 7. 添加用户到角色
ALTER ROLE fgedu_readonly_role ADD MEMBER fgedu_readonly;
GO

Command(s) completed successfully.

# 8. 验证只读权限
EXECUTE AS USER = ‘fgedu_readonly’;
GO

# 测试SELECT(应该成功)
SELECT TOP 5 * FROM business.fgedu_orders;
GO

order_id customer_name order_date total_amount
——– ————- ———– ————
101 张三 2026-04-01 1500.00
102 李四 2026-04-02 2300.00
103 王五 2026-04-03 1800.00
104 赵六 2026-04-04 3200.00
105 钱七 2026-04-05 2100.00

# 测试INSERT(应该失败)
INSERT INTO business.fgedu_orders (customer_name, order_date, total_amount)
VALUES (‘测试用户’, GETDATE(), 100.00);
GO

Msg 229, Level 14, State 5, Line 1
The INSERT permission was denied on the object ‘fgedu_orders’, database ‘fgedudb’, schema ‘business’.

# 恢复原始用户
REVERT;
GO

Command(s) completed successfully.

4.3 SQLServer数据库权限问题解决方案

# 常见权限问题及解决方案

# 问题1:用户无法访问表
# 排查步骤:

# 检查用户是否存在
SELECT name, type_desc FROM sys.database_principals WHERE name = ‘fgedu_user’;
GO

name type_desc
———- ———-
fgedu_user SQL_USER

# 检查用户角色成员
SELECT dr.name AS RoleName
FROM sys.database_role_members drm
JOIN sys.database_principals dr ON drm.role_principal_id = dr.principal_id
WHERE drm.member_principal_id = (
SELECT principal_id FROM sys.database_principals WHERE name = ‘fgedu_user’
);
GO

RoleName
—————
db_datareader

# 检查用户权限
SELECT permission_name, state_desc, OBJECT_NAME(major_id) AS ObjectName
FROM sys.database_permissions
WHERE grantee_principal_id = (
SELECT principal_id FROM sys.database_principals WHERE name = ‘fgedu_user’
);
GO

permission_name state_desc ObjectName
————— ———- ———–
SELECT GRANT NULL

# 问题2:权限冲突
# 检查DENY权限
SELECT USER_NAME(grantee_principal_id) AS Grantee,
permission_name, state_desc, OBJECT_NAME(major_id) AS ObjectName
FROM sys.database_permissions
WHERE state_desc = ‘DENY’
AND USER_NAME(grantee_principal_id) IN (‘fgedu_user’, ‘public’);
GO

Grantee permission_name state_desc ObjectName
———- ————— ———- ———–
fgedu_user DELETE DENY fgedu_orders

# 问题3:权限继承问题
# 检查用户的所有权限来源
CREATE PROCEDURE sp_fgedu_check_permissions
@username NVARCHAR(128)
AS
BEGIN
PRINT ‘=== 用户权限检查报告 ===’;
PRINT ‘用户名: ‘ + @username;
PRINT ”;

PRINT ‘1. 直接授予的权限:’;
SELECT permission_name, state_desc,
CASE WHEN major_id = 0 THEN ‘DATABASE’
ELSE OBJECT_NAME(major_id) END AS ObjectName
FROM sys.database_permissions
WHERE grantee_principal_id = (
SELECT principal_id FROM sys.database_principals WHERE name = @username
);

PRINT ”;
PRINT ‘2. 通过角色获得的权限:’;
SELECT dr.name AS RoleName, dp.permission_name, dp.state_desc
FROM sys.database_role_members drm
JOIN sys.database_principals dr ON drm.role_principal_id = dr.principal_id
JOIN sys.database_permissions dp ON dp.grantee_principal_id = dr.principal_id
WHERE drm.member_principal_id = (
SELECT principal_id FROM sys.database_principals WHERE name = @username
);
END;
GO

Command(s) completed successfully.

# 执行权限检查
EXEC sp_fgedu_check_permissions ‘fgedu_app’;
GO

=== 用户权限检查报告 ===
用户名: fgedu_app

1. 直接授予的权限:
permission_name state_desc ObjectName
————— ———- ———-
SELECT GRANT fgedu_orders
INSERT GRANT fgedu_orders

2. 通过角色获得的权限:
RoleName permission_name state_desc
————— ————— ———-
db_datareader SELECT GRANT
db_datawriter INSERT GRANT
db_datawriter UPDATE GRANT
db_datawriter DELETE GRANT

生产环境建议:建立权限问题排查流程,使用脚本定期检查权限配置,及时发现和解决权限问题。from SQLServer视频:www.itpux.com

Part05-风哥经验总结与分享

5.1 SQLServer数据库角色权限最佳实践

SQLServer数据库角色权限最佳实践:

  • 使用角色管理权限:通过角色而非直接授权管理权限
  • 遵循最小权限原则:只授予必要的权限
  • 定期审查权限:每季度审查用户权限配置
  • 记录权限变更:保留权限变更历史记录
  • 使用自定义角色:根据业务需求创建自定义角色
  • 避免过度授权:谨慎使用db_owner和sysadmin角色

5.2 SQLServer数据库权限检查清单

# SQLServer数据库权限检查清单

1. 服务器角色检查
[ ] sysadmin角色成员是否合理
[ ] 是否有自定义服务器角色
[ ] 服务器权限是否最小化

2. 数据库角色检查
[ ] db_owner角色成员是否合理
[ ] 是否有自定义数据库角色
[ ] public角色权限是否合理

3. 用户权限检查
[ ] 是否有无用账户
[ ] 权限是否最小化
[ ] 是否有权限冲突

4. 对象权限检查
[ ] 敏感表权限是否受控
[ ] 存储过程执行权限是否合理
[ ] 是否有列级别权限控制

5. 权限审计检查
[ ] 是否有权限变更记录
[ ] 是否有定期权限审查
[ ] 是否有权限告警机制

5.3 SQLServer数据库权限管理工具推荐

SQLServer数据库权限管理工具推荐:

  • SSMS:图形化管理角色和权限
  • 系统视图:sys.server_principals、sys.database_principals
  • 权限查询脚本:自定义脚本检查权限配置
  • 第三方工具:专业的权限管理和审计工具
风哥提示:权限管理是数据库安全的核心,需要建立完善的管理制度和流程。建议定期培训相关人员,确保权限配置合理、安全。更多视频教程www.fgedu.net.cn

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息