RBAC role-based rights management - design 1.0
What is RBAC
Role-based permission management. Simply put, a user can have several roles, and a role can have several permissions. This forms a "user-role-permission" model.
Basic table design
- Database using MySql
- This table design only uses the most basic fields
- Ignore the field length, if you use this design, please modify it yourself
- Ignore foreign key construction, if you adopt this design, please create it yourself
user table
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`create_user` datetime DEFAULT NULL COMMENT '创建人',
`login_time` datetime DEFAULT NULL COMMENT '登录时间',
`name` varchar(255) DEFAULT NULL COMMENT '用户名称',
`password` varchar(255) DEFAULT NULL COMMENT '登录密码',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`status` int(11) DEFAULT NULL COMMENT '用户状态',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`update_user` datetime DEFAULT NULL COMMENT '更新人员',
`username` varchar(255) DEFAULT NULL COMMENT '登录名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
role table
CREATE TABLE `t_role` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色id',<br/>
`role_name` varchar(255) DEFAULT NULL COMMENT '角色名称',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Permissions table
CREATE TABLE `t_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限ID',
`permission_code` varchar(255) DEFAULT NULL COMMENT '权限编码',
`permission_name` varchar(255) DEFAULT NULL COMMENT '权限名称',
`pid` int(11) DEFAULT NULL COMMENT '父类权限ID(依赖权限)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
User role relationship table
CREATE TABLE `t_user_role` (
`user_id` int(11) NOT NULL COMMENT '用户id',
`role_id` int(11) NOT NULL COMMENT '角色id',
PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Role permission relationship table
CREATE TABLE `t_role_permission` (
`role_id` int(11) NOT NULL COMMENT '角色id',
`permission_id` int(11) NOT NULL COMMENT '权限id',
PRIMARY KEY (`role_id`,`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Access control
control menu
Scenes
Administrators and Ordinary Members. For example, the administrator can see all the menus, and ordinary members can only see a part of the menu (or can see it, but when clicked, a prompt that there is no permission to operate will pop up. Due to personal preferences and personal experience deviations, this article does not take this approach. way).
The question is, how to control the menu permissions of roles? let's go! ! !
table design
CREATE TABLE `t_menu` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`menu_name` varchar(255) DEFAULT NULL COMMENT '菜单名称',
`permission_code` varchar(255) DEFAULT NULL COMMENT '权限编码(菜单编码)',
`pid` int(11) DEFAULT NULL COMMENT '父菜单id',
`url` varchar(255) DEFAULT NULL COMMENT '菜单url跳转链接',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Brief business process diagram
Detailed business flow chart
control button
Scenes
With menu permissions, it still cannot meet the needs of some scenarios. For example, when multiple roles have the A menu at the same time, role 1 can have the permissions to query and create, and role 2 has the permissions to query, create, modify, and delete. That is, role 1 can only see the query and create buttons, and role 2 can see the query, create, modify, and delete buttons. At this time, how should we deal with it?
accomplish
-
Button permission definition: define lower-level permission query, create, modify, delete under menu permissions, such as Aquery, Aadd, Aupdate, Adelete.
-
Here it is used in combination with shiro (please leave a message for those who don't use it, and add the solution later) : Use shiro:hasPermission in the page where the A menu jumps to achieve the effect of the control button. E.g
<shiro:hasPermission name="Aadd"> <button>新建<button> </shiro:hasPermission>
Detailed business flow diagram (in combination with shiro)
Code example (ideas matter)
Check if user has menu permission
/**
* 检查用户是否有菜单权限
*
* @param menus
* 所有菜单
* @param subject
* shiro用户信息
* @return 用户已分配的菜单集合
*/
private List<Menu> check(List<Menu> menus, Subject subject) {
List<Menu> res = new ArrayList<Menu>();
for (Menu m1 : menus) {
if (StringUtils.isEmpty(m1.getPermissionCode())) {
continue;
}
// 这里会触发鉴权操作
if (subject.isPermitted(m1.getPermissionCode())) {
res.add(m1);
}
}
return res;
}
Custom realm-authentication operation
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 查询当前用户所有权限
List<Permission> infos = userService.findMyPermitions();
// 权限集合(这里我习惯把权限编码放进去)
Set<String> permissions = new HashSet<String>();
// 角色集合(这里放角色ID)
Set<String> roles = new HashSet<String>();
if (infos != null && infos.size() > 0) {
for (Permission info : infos) {
permissions.add(info.getPermissionCode());
roles.add(info.getRoleId());
}
}
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setStringPermissions(permissions);
authorizationInfo.setRoles(roles);
return authorizationInfo;
}
data permission
Scenes
Some businesses may be like this. A list (or table), which requires ordinary users to only see the list information created by themselves, and business department managers can only see all the list information of this department. How to control this permission?
accomplish
See the reaction, see you next time.