跳到主要内容

权限管理

问题

数据库的权限管理体系是什么?如何实现最小权限原则?

答案

一、权限管理层次

二、MySQL 权限管理

用户与权限

-- 创建用户(限定来源 IP)
CREATE USER 'app_user'@'10.0.0.%' IDENTIFIED BY 'StrongPass123!';

-- 授予权限(按需分配)
-- 应用账号:只允许 DML
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'10.0.0.%';

-- 只读账号
GRANT SELECT ON mydb.* TO 'readonly_user'@'10.0.0.%';

-- 管理员账号(仅限特定 IP)
GRANT ALL PRIVILEGES ON mydb.* TO 'admin_user'@'10.0.1.100';

-- 细粒度:只允许查某些列
GRANT SELECT (id, name, email) ON mydb.users TO 'limited_user'@'10.0.0.%';

-- 查看权限
SHOW GRANTS FOR 'app_user'@'10.0.0.%';

-- 撤销权限
REVOKE DELETE ON mydb.* FROM 'app_user'@'10.0.0.%';

-- 刷新权限
FLUSH PRIVILEGES;

常见权限列表

权限说明风险等级
SELECT查询
INSERT插入
UPDATE更新
DELETE删除
CREATE建表/建库
DROP删表/删库极高
ALTER修改表结构
GRANT授权给其他用户极高
SUPER超级权限极高
FILE读写服务器文件极高

三、PostgreSQL 权限管理

PostgreSQL 提供更精细的权限模型:

-- 创建角色
CREATE ROLE app_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_role;

-- 创建用户(用户 = 可登录的角色)
CREATE USER app_user WITH PASSWORD 'StrongPass123!' IN ROLE app_role;

-- Schema 级权限
GRANT USAGE ON SCHEMA public TO app_role;

-- 序列权限(自增 ID 需要)
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_role;

-- 默认权限(新建表自动继承)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_role;

行级安全(Row Level Security)

PostgreSQL 支持 RLS,限制用户只能访问特定行:

-- 启用行级安全
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- 策略:用户只能看自己的订单
CREATE POLICY user_orders ON orders
FOR ALL
USING (user_id = current_setting('app.current_user_id')::INT);

-- 应用中设置当前用户
SET app.current_user_id = '42';
SELECT * FROM orders; -- 只返回 user_id = 42 的订单
RLS 的优势
  • 安全下沉到数据库层:即使应用SQL写错了也不会泄露数据
  • 对 ORM 透明:不需要修改查询逻辑
  • Supabase 大量使用 RLS 实现多租户隔离

四、最小权限原则实践

┌────────────────────────────────────────────────┐
│ 数据库账号分类 │
├──────────────┬──────────────┬──────────────────┤
│ 应用账号 │ 运维账号 │ 分析账号 │
│ SELECT/INSERT │ CREATE/ALTER │ SELECT │
│ UPDATE/DELETE │ DROP/BACKUP │ (只读副本) │
│ 限定应用 IP │ 限定堡垒机 IP │ 限定 BI 工具 IP │
└──────────────┴──────────────┴──────────────────┘
原则具体做法
按角色分配应用、DBA、分析师使用不同账号
按环境隔离开发、测试、生产使用不同账号和密码
限制来源 IP应用账号限定应用服务器 IP 段
禁用 root 远程root@localhost 仅限本地操作
定期审查定期清理不再使用的账号
密码策略强密码 + 定期轮换

五、多租户数据隔离

方案说明隔离级别成本
独立数据库每个租户一个库最强最高
独立 Schema同库不同 Schema
共享表 + tenant_idWHERE 条件过滤最低
共享表 + RLS行级安全策略中偏强

常见面试问题

Q1: 为什么不能用 root 账号连接生产数据库?

答案

  1. 权限过大:root 可以 DROP DATABASE、修改其他用户权限
  2. 无法审计:所有操作都用 root,无法追溯具体操作人
  3. 安全风险:一旦密码泄露,攻击者获得完整控制权
  4. 误操作:DELETE 忘了 WHERE 条件直接清空表

Q2: 如何实现数据库连接的安全认证?

答案

  1. 强密码策略:16+ 字符,包含大小写、数字、特殊字符
  2. SSL/TLS 连接:加密传输层,防止密码嗅探
  3. 证书认证:使用 x509 客户端证书(替代密码)
  4. IAM 认证:云数据库(如 AWS RDS)支持 IAM 临时凭证
  5. 密钥管理:密码存储在 Vault 等密钥管理系统,而非代码或配置文件

Q3: 什么是 RBAC?在数据库中如何实现?

答案

RBAC(Role-Based Access Control)基于角色的访问控制:

-- 定义角色
CREATE ROLE app_readonly;
CREATE ROLE app_readwrite;
CREATE ROLE app_admin;

-- 角色授权
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_readonly;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_readwrite;
GRANT ALL PRIVILEGES ON SCHEMA public TO app_admin;

-- 用户分配角色
GRANT app_readonly TO analyst_user;
GRANT app_readwrite TO app_user;
GRANT app_admin TO dba_user;

好处:权限管理集中在角色上,人员变动时只需修改角色分配。

相关链接