前言
权限管理是在项目中经常要使用到的模块,有着极其重要的功能。 在 Java 帝国中有两个比较出名的权限框架,分别为 Shiro 和 Spring Security,两者各有优缺,但这不是本篇要讨论的重点,这次我们不用任何权限框架来实现 RBAC 权限管理。
本文所有代码下载地址:https://github.com/zhaojun1998/Premission-Study
RBAC 简介
RBAC (Role-Based Access Control) 基于角色的权限访问控制。
即用户拥有角色,角色拥有权限。具体关于 RBAC 的好处我就不再赘言,如感兴趣请自行查询。
数据库设计
共有五张表,分别为用户表、角色表、权限表、用户-角色关系表、角色-权限关系表。其中用户表于角色表是多对多的关系,角色表于权限表也是多对多关系。具体每个字段的含义请查看相应的注释。
1 | SET NAMES utf8mb4; |
环境配置
本次基于的环境是 Spring + SpringMVC + MyBatis,不过即使你不会这几个框架也无所谓,因为权限管理没有涉及到太多这些框架的特性,用普通的 Servlet + JDBC 同样也可以实现。
因篇幅原因,框架的配置文件我这里就不再贴出,但我会将源码发到 Github,你可以去下载本实例完整代码。
实体类
首先需要创建三个与数据库对应的实体类
1 | public class User { |
1 | public class Role { |
1 | public class Permission { |
DAO 数据操作层
UserMapper
1 | public interface UserMapper { |
RoleMapper
1 | public interface RoleMapper { |
PermissionMapper
1 | public interface PermissionMapper { |
只需要一些简单的 SQL 操作,如需要对应的 mapper.xml 可去 Github 查看。
用户管理
用户添加
HTML 页面:
1 | <form action="addUser" method="post"> |
Controller:
1 | public String addUserSubmit(User user) { |
service 和 dao 略.
用户登陆
HTML 页面:
1 | <form action="login" method="post"> |
Controller:
1 | public String login(String username, String password, HttpSession httpSession) { |
service 和 dao 略.
查看用户列表
HTML 页面:
1 | <table border="1"> |
Controller:
1 | public ModelAndView listUser() { |
service 和 dao 略.
为用户赋予角色
为用户赋予角色需要先添加角色,请先看下面的添加角色后再来操作。
HTML 页面:
1 | <form action="grantRole"> |
Controller:
1 | public String grantRole(int id, int[] roleId) { |
Service:
1 | public void updateRoles(Integer id, int[] roleIds) { |
其实这里的修改授权角色只是将原来它拥有的所有角色删除,再分配给它提交的所有角色。
角色管理
添加角色
HTML 页面:
1 | <form action="addRole" method="post"> |
Controller:
1 | public String addRole(Role role) { |
service 和 dao 略.
角色列表
HTML 页面:
1 | <table border="1"> |
Controller:
1 | public ModelAndView listRole() { |
service 和 dao 略.
为角色赋予权限
HTML 页面:
1 | <form action="grantPermission"> |
Controller:
1 | public String grantPermission(int id, int[] premissionId) { |
Service:
1 | public void updatePermission(Integer roleId, int[] permissionsIds) { |
这里的为角色赋予权限同样也是先删除角色所拥有的权限,再添加表单提交的所有权限。
权限管理
添加权限
HTML 页面:
1 | <form action="addPermission" method="post"> |
Controller:
1 | public String add(Permission permission) { |
service 和 dao 略.
权限列表
HTML 页面:
1 | <form action="addPermission" method="post"> |
Controller:
1 | public String add(Permission permission) { |
service 和 dao 略.
权限拦截
既然已经分配好用户,角色以及权限之间的关系了,那么我们就可以设置一些需要权限才能访问的资源了。
我设置了 5 个 url, 并标注了需要何权限或何角色才可访问:
1 | /api/add # add 权限 |
我们可以用拦截器来拦截 /api/*
下的所有请求,那么如何区分不同请求分别需要什么权限呢?
这里我参考了 Shiro 的设计,即采用注解的方式,在相应的方法上用 @RequiredRole
和 @RequiredPremission
来标注相应的请求需要某个角色或某个权限才可访问。
1 |
|
拦截器获取拦截的方法上的注解即可得知需要什么权限,以便来进行相应的判断,Spring 拦截器:
1 | public class PermissionHandlerInterceptor implements HandlerInterceptor { |
总结
基本实现就这些,其实没有很复杂的东西,只是将 RBAC 这个思想运用了起来。
那么反观我们这个权限管理有什么缺陷呢?
我来列举几点:
- 对密码没有进行加密处理, 应对密码进行加盐并散列。
- 每次请求都会去获取所对应的权限数据和角色数据,太耗费资源,应该进行缓存。
- 不支持多凭证登陆,如可用邮箱也可用手机号登陆。
这些问题我会在后续的 shiro 的笔记中一一讲到。
本文所有代码下载地址:https://github.com/zhaojun1998/Premission-Study