权限操作:RBAC+ACL搭配
1. RBAC(基于角色的访问控制)
RBAC将权限分配给角色,用户通过关联角色间接获得权限。系统通过“用户-角色-权限”的层级关系实现权限管理。
这种经典的权限控制设计有一个缺点,就是难以处理特殊个体的细粒度权限,比如我作为管理员,我需要将某个文件的访问权限交给不是管理员,但是信任的人(比如张三)进行访问。
2. ACL(访问控制列表)
ACL直接在资源上定义允许操作的主体,每条记录明确指定"谁可以对某资源做什么"
这种划分权限类似于我们平常使用的windows文件管理的方式,其主要优势在于灵活性强,每条权限规则都明确可见。但是缺点也很明显,那就是当用户数量或者资源数量很大的时候,ACL条目呈现指数级增长。
3. RBAC 与 ACL 联合使用的优势
-
灵活性与效率的平衡
- RBAC 处理通用权限(如部门角色、职级权限)
- ACL 处理例外场景(如特殊用户需要访问特定资源)
比如,在企业系统中,普通员工通过角色获得基础权限,但某个机密文件可通过ACL单独授权给少数高管。
-
减少角色爆炸
- 通过ACL补充RBAC,避免在RBAC中因为个别的特殊权限去创建冗余角色
-
精细化权限管理
- RBAC管理粗粒度权限(如”访问财务模块“),ACL控制细粒度操作(如”仅能查看报表,不能导出“)
-
冲突解决与优先级
- 当RBAC和ACL权限有冲突的时候,可以设定优先级,比如ACL优先于RBAC
4. RBAC + ACL模型举例
RBAC(基于角色的访问控制)经典模型中通常包含以下5张核心表:
-- 1. 用户表(3个用户)
CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100)
);
INSERT INTO users (username, email) VALUES
('alice', 'alice@example.com'), -- admin
('bob', 'bob@example.com'), -- user
('charlie', 'charlie@example.com'); -- user
-- 2. 角色表(admin 和 user)
CREATE TABLE roles (
role_id INT PRIMARY KEY AUTO_INCREMENT,
role_name VARCHAR(50) NOT NULL UNIQUE
);
INSERT INTO roles (role_name) VALUES
('admin'),
('user');
-- 3. 权限表(只包含读和写)
CREATE TABLE permissions (
permission_id INT PRIMARY KEY AUTO_INCREMENT,
permission_key VARCHAR(50) NOT NULL UNIQUE
);
INSERT INTO permissions (permission_key) VALUES
('article:read'),
('article:write');
-- 4. 用户-角色关联表
CREATE TABLE user_roles (
user_id INT,
role_id INT,
PRIMARY KEY (user_id, role_id),
FOREIGN KEY (user_id) REFERENCES users(user_id),
FOREIGN KEY (role_id) REFERENCES roles(role_id)
);
-- 分配角色(1个admin,2个user)
INSERT INTO user_roles (user_id, role_id) VALUES
(1, 1), -- alice 是 admin
(2, 2), -- bob 是 user
(3, 2); -- charlie 是 user
-- 5. 角色-权限关联表
CREATE TABLE role_permissions (
role_id INT,
permission_id INT,
PRIMARY KEY (role_id, permission_id),
FOREIGN KEY (role_id) REFERENCES roles(role_id),
FOREIGN KEY (permission_id) REFERENCES permissions(permission_id)
);
-- 权限分配:admin有读写,user只有读
INSERT INTO role_permissions (role_id, permission_id) VALUES
(1, 1), -- admin -> article:read
(1, 2), -- admin -> article:write
(2, 1); -- user -> article:read
然后如果需要对权限进行更加细粒度的控制,有如下ACL表可供参考:
CREATE TABLE acl_entry (
id INT PRIMARY KEY AUTO_INCREMENT,
resource_type VARCHAR(50) NOT NULL, -- 资源类型,如 article、order、comment
resource_id INT NOT NULL, -- 具体资源ID
grantee_type ENUM('USER', 'ROLE') NOT NULL, -- 授权对象类型:用户或角色
grantee_id INT NOT NULL, -- 被授权的用户或角色的ID
permission VARCHAR(20) NOT NULL, -- 权限类型,如 read、write
created_by INT NOT NULL, -- 授权人ID
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_acl_entry(resource_type, resource_id, grantee_type, grantee_id)
);
-- admin (user_id = 1) 给用户 (user_id = 2) 授权了对文章101的读权限
-- admin 给角色(role_id = 2,可能是 editor)授权了对文章101的写权限
INSERT INTO acl_entry (resource_type, resource_id, grantee_type, grantee_id, permission, created_by) VALUES
('article', 101, 'USER', 2, 'read', 1),
('article', 101, 'ROLE', 2, 'write', 1);