在数据库权限管理中,直接授予用户表的查询权限会导致所有列都可被访问,若表中存在手机号、身份证号等敏感字段,很容易引发数据泄露问题。通过视图筛选指定列,再结合基于角色的权限控制,既能满足用户的业务查询需求,又能有效保护敏感数据。
通过视图限制用户访问列的实现方法
视图本质是虚拟表,它的数据来源于基础表的查询结果,我们可以在创建视图时指定需要暴露的列,从而隐藏不需要让用户访问的字段。
1. 基础表的准备
首先我们创建一个包含敏感字段的用户信息表作为示例:
-- 创建用户基础表
CREATE TABLE user_info (
user_id INT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL,
phone VARCHAR(20) NOT NULL,
id_card VARCHAR(18) NOT NULL,
register_time DATETIME NOT NULL
);
-- 插入测试数据
INSERT INTO user_info VALUES
(1, '张三', '13800138000', '110101199001011234', '2023-01-01 10:00:00'),
(2, '李四', '13900139000', '110101199002022345', '2023-01-02 11:00:00');
2. 创建仅暴露非敏感列的视图
假设业务只需要用户查询user_id、user_name、register_time这三个字段,我们可以创建如下视图:
-- 创建视图,仅包含允许访问的列 CREATE VIEW user_public_view AS SELECT user_id, user_name, register_time FROM user_info;
此时查询该视图,只会返回我们指定的三个列,phone和id_card等敏感字段不会被暴露:
-- 查询视图验证结果 SELECT * FROM user_public_view;
基于角色的权限控制配置
如果直接把视图的查询权限授予每个用户,当用户数量较多时管理成本会很高,通过角色可以批量管理权限,后续新增或调整权限时只需要修改角色即可。
1. 创建角色并分配视图权限
首先创建一个专门用于查询用户公开信息的角色:
-- 创建角色,不同数据库创建角色的语法略有差异,以下为通用写法 CREATE ROLE user_query_role; -- 授予角色查询视图的权限 GRANT SELECT ON user_public_view TO user_query_role;
2. 将角色绑定到用户
创建好角色后,将角色授予需要访问该视图的用户即可:
-- 假设已存在用户 test_user,将角色授予该用户 GRANT user_query_role TO test_user; -- 部分数据库需要设置角色为默认启用,以PostgreSQL为例 ALTER ROLE test_user SET ROLE user_query_role;
3. 验证权限效果
使用test_user登录数据库后,尝试查询基础表会被拒绝,只能查询视图:
-- 尝试查询基础表,会提示无权限 SELECT * FROM user_info; -- 查询视图,可正常返回数据 SELECT * FROM user_public_view;
不同数据库的语法差异说明
不同关系型数据库的视图和角色语法存在一定差异,以下是常见数据库的差异点:
| 数据库类型 | 角色创建语法 | 视图权限授予语法 |
|---|---|---|
| MySQL 8.0+ | CREATE ROLE 'user_query_role'@'localhost'; | GRANT SELECT ON test_db.user_public_view TO 'user_query_role'@'localhost'; |
| PostgreSQL | CREATE ROLE user_query_role NOLOGIN; | GRANT SELECT ON user_public_view TO user_query_role; |
| SQL Server | CREATE ROLE user_query_role; | GRANT SELECT ON user_public_view TO user_query_role; |
注意事项
- 视图本身不存储数据,每次查询视图都会重新执行基础表的查询逻辑,若基础表数据量较大,建议给视图涉及的基础表字段添加合适索引。
- 若后续基础表结构变更,需要同步检查视图的逻辑是否需要调整,避免出现查询错误。
- 角色的权限可以叠加,如果一个用户需要多个不同的视图访问权限,可以将多个角色授予该用户。
- 如果需要回收权限,直接回收角色的权限即可,所有绑定该角色的用户都会同步失去对应权限。
视图结合角色权限控制的方式属于数据库层的权限管控,适合做粗粒度到中粒度的权限管理,若需要更细粒度的行级权限控制,可以结合视图的行筛选条件或者数据库的行级安全策略实现。