最近,一位朋友在面试中被问及如何设计一个权限系统。我们注意到目前许多后台管理系统(包括一些热门的如若依快速开发平台)都采用了RBAC访问控制策略。该策略通过将权限授予角色,然后将角色分配给用户,从而实现对系统资源的访问控制。今天,我们将详细解释基于RBAC的权限系统。
RBAC描述
RBAC(Role-Based Access Control)是一种访问控制模型,其核心概念是基于角色的权限分配。该模型的设计目标是简化对系统资源的访问管理,提高系统的安全性和可维护性。
RBAC的实现通常包括以下步骤:
- 设计角色和权限的层次结构。
- 将用户分配到合适的角色。
- 关联权限到角色,形成访问控制矩阵。
- 通过会话管理机制维护权限的有效性。
以下是RBAC权限系统的一些描述:
角色定义
在RBAC系统中,角色是一组相互关联的权限的集合。角色可以代表用户的职能、职位或责任。例如,系统管理员、普通用户、审计员等都可以是角色。在一些企业中权限系统中,他们采用的三权分立的权限体系,就是通过角色和用户的类型来控制的。
权限定义
权限表示对系统资源或操作的访问权力,包括不同级别的访问,如读、写、执行等操作。通常,权限与具体任务或操作相关联,例如访问特定文件、修改用户信息等。在我们的权限系统中,权限的粒度一般细化到页面上的操作按钮级别。一些系统还包含数据权限,例如可以访问当前部门及其下级部门的数据,或者只能查看特定系统的数据等。
角色分配
用户通过被分配到一个或多个角色而获得相应的权限。这使得权限管理更加简化,因为不再需要为每个用户直接分配权限,而只需管理角色与权限的关系。
权限关联
每个角色都与特定的权限相关联。这意味着当用户被分配到某个角色时,他们将自动拥有该角色所关联的权限。这种关联可以通过访问控制矩阵或类似的结构来实现。
会话管理
用户登录系统后,会话管理机制负责维护用户与其角色相关联的权限。一旦会话结束,通常会触发权限的自动撤销。我们通常采用将会话存储到Redis中,并设置过期时间的方式来管理会话。用户在访问时会刷新过期时间,确保会话的有效性。
审计和监控
RBAC系统通常包括审计和监控功能,以便记录用户活动、权限变更和系统访问情况。这有助于检测潜在的安全问题和确保合规性。
动态调整:
RBAC系统允许在运行时动态调整角色和权限的关联关系。这种灵活性使得系统能够适应不断变化的组织结构和业务需求。
RBAC的特点
- 简化管理
通过将权限关联到角色,RBAC简化了大规模用户权限管理的复杂性。
- 灵活性
RBAC模型具有较强的灵活性,可以根据组织需求调整角色和权限的关联关系。
- 降低错误
通过减少直接分配权限给用户的操作,RBAC降低了由于错误授权导致的系统安全风险。
数据库表设计
数据库表ER图如下:
具体表设计如下:
sys_menu
表注释: 菜单权限表
字段 | 类型 | 空 | 默认 | 注释 |
id (主键) | bigint | 否 | 菜单ID | |
menu_name | varchar(50) | 是 | NULL | 菜单名称 |
parent_id | bigint | 是 | 0 | 父菜单ID |
order_num | int | 是 | 0 | 显示顺序 |
path | varchar(200) | 是 | 路由地址 | |
component | varchar(255) | 是 | NULL | 组件路径 |
query | varchar(255) | 是 | NULL | 路由参数 |
is_frame | int | 是 | 1 | 是否为外链(0是 1否) |
menu_type | char(1) | 是 | 菜单类型(M目录 C菜单 F按钮) | |
visible | char(1) | 是 | 0 | 菜单状态(0显示 1隐藏) |
status | char(1) | 是 | 0 | 菜单状态(0正常 1停用) |
perms | varchar(100) | 是 | NULL | 权限标识 |
icon | varchar(100) | 是 | # | 菜单图标 |
create_by | varchar(64) | 是 | 创建者 | |
create_time | datetime | 是 | NULL | 创建时间 |
update_by | varchar(64) | 是 | 更新者 | |
update_time | datetime | 是 | NULL | 更新时间 |
remark | varchar(500) | 是 | 备注 |
sys_role
表注释: 角色信息表
字段 | 类型 | 空 | 默认 | 注释 |
id (主键) | bigint | 否 | 角色ID | |
role_name | varchar(30) | 是 | NULL | 角色名称 |
role_key | varchar(100) | 是 | NULL | 角色权限字符串 |
status | char(1) | 是 | NULL | 角色状态(0正常 1停用) |
del_flag | char(1) | 是 | 0 | 删除标志(0代表存在 2代表删除) |
create_by | varchar(64) | 是 | 创建者 | |
create_time | datetime | 是 | NULL | 创建时间 |
update_by | varchar(64) | 是 | 更新者 | |
update_time | datetime | 是 | NULL | 更新时间 |
remark | varchar(500) | 是 | NULL | 备注 |
sys_role_menu
表注释: 角色和菜单关联表
字段 | 类型 | 空 | 默认 | 注释 |
id (主键) | bigint | 否 | ||
role_id | bigint | 是 | NULL | 角色ID |
menu_id | bigint | 是 | NULL | 菜单ID |
sys_user
表注释: 用户信息表
字段 | 类型 | 空 | 默认 | 注释 |
id (主键) | bigint | 否 | 用户ID | |
user_name | varchar(30) | 是 | NULL | 用户账号 |
nick_name | varchar(30) | 是 | NULL | 用户昵称 |
phonenumber | varchar(11) | 是 | 手机号码 | |
password | varchar(100) | 是 | 密码 | |
status | char(1) | 是 | 0 | 帐号状态(0正常 1停用) |
del_flag | char(1) | 是 | 0 | 删除标志(0代表存在 2代表删除) |
create_by | varchar(64) | 是 | 创建者 | |
create_time | datetime | 是 | NULL | 创建时间 |
update_by | varchar(64) | 是 | 更新者 | |
update_time | datetime | 是 | NULL | 更新时间 |
remark | varchar(500) | 是 | NULL | 备注 |
sys_user_role
表注释: 用户和角色关联表
字段 | 类型 | 空 | 默认 | 注释 |
id (主键) | bigint | 否 | 主键ID | |
user_id | bigint | 是 | NULL | 用户ID |
role_id | bigint | 是 | NULL | 角色ID |
sys_logininfor
表注释: 系统登录日志表
字段 | 类型 | 空 | 默认 | 注释 |
id (主键) | bigint | 否 | 访问ID | |
user_id | bigint | 是 | NULL | 用户id |
user_name | varchar(50) | 是 | 用户账号 | |
ipaddr | varchar(128) | 是 | 登录IP地址 | |
login_location | varchar(255) | 是 | 登录地点 | |
browser | varchar(50) | 是 | 浏览器类型 | |
os | varchar(50) | 是 | 操作系统 | |
status | char(1) | 是 | 0 | 登录状态(0成功 1失败) |
msg | varchar(255) | 是 | 提示消息 | |
login_time | datetime | 是 | NULL | 访问时间 |
总结
RBAC权限系统作为一种可靠而强大的访问控制机制,为系统安全提供了坚实的基础。通过深入理解RBAC的核心概念和工作原理,我们可以更好地应用该模型,确保系统在访问控制方面达到最佳性能,同时提高系统的可维护性和灵活性。一些系统在基于RBAC角色系统的基础上引入了临时角色、基础角色等功能,以进一步完善RBAC的灵活性和适应性。