标签:基于 拦截器 角色 RBAC 001 编号 权限 class
基于RBAC实现权限管理
技术栈:SpringBoot、SpringMVC
RBAC
RBAC数据库表
主体
编号 | 账号 | 密码 |
---|---|---|
001 | admin | 123456 |
资源
编号 | 资源名称 | 访问路径 |
---|---|---|
001 | 查询用户列表 | /user/list |
权限
编号 | 权限标识 | 权限名称 | 资源编号 |
---|---|---|---|
001 | user:list | 查看用户列表 | 001 |
角色
角色编号 | 角色名称 |
---|---|
001 | 管理员 |
用户角色
编号 | 角色编号 | 用户编号 |
---|---|---|
001 | 001 | 001 |
角色权限
编号 | 角色编号 | 权限编号 |
---|---|---|
001 | 001 | 001 |
可以进行一些合并,优化表数量
将资源表和权限表进行合并为权限表
权限
编号 | 权限标识 | 权限名称 | 资源名称 | 资源访问地址 |
---|---|---|---|---|
001 | user:list | 查询用户列表 | 用户列表 | /user/list |
基于角色的访问控制(Role-Based Access Control)
主要思想就是访问后台接口的时候判断该用户的角色是否为某某角色,是的话就放行,否则就拒绝访问。
这里我用的jwt,token里存储的由用户角色(ADMIN)
实现方式:自定义注解+拦截器
自定义注解
@Target({ElementType.METHOD}) //注解作用域方法上
@Retention(RetentionPolicy.RUNTIME) //编译器将注解信息存储与class文件中,由JVM读取
@Documented
public @interface HasRole {
String[] value() default {};
}
SpringMVC拦截器
@Component
public class AccessControlInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
if (handlerMethod.hasMethodAnnotation(HasRole.class)) {
// 从request中获取token
// 解析token获取claims
// claims就是个map,直接获取用户角色
String role = claims.get("userRole");
String[] hasRole = handlerMethod.getMethodAnnotation(HasRole.class).value();
boolean contains = Arrays.asList(hasRole).contains(role);
if(!contains){
// 不符合条件,可以抛自定义异常,给客户端提示信息
return false;
}
}
}
return true;
}
}
注意:最后要把拦截器加入到配置里面
这种方式很简单,应对简单的需求很实用,但是复杂的就行不通了
基于资源的访问控制(Resource-Based Access Control)
主要思想,由于资源是不会变的,我们给角色或者用户分配资源权限后,直接在拦截器里面进行资源权限的校验即可。且有变动的时候基本上不需要改动代码。
用户登录的后把用户的资源权限查出来放到redis里面
实现方式依旧:自定义注解+拦截器
自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HasResourcePermission {
String value() default "";
}
SpringMVC拦截器
@Component
public class RequestInterceptor implements HandlerInterceptor {
@Resource
private RedisTemplate<String,Object> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
if (handlerMethod.hasMethodAnnotation(HasResourcePermission.class)) {
String resourcePermissionSign = handlerMethod.getMethodAnnotation(HasResourcePermission.class).value();
Object resourcePermission = redisTemplate.opsForValue().get("resourcePermission");
List<String> resourcePermissionList = (List<String>) resourcePermission;
if (resourcePermissionList.contains(resourcePermissionSign)) {
// 不符合条件,可以抛自定义异常,给客户端提示信息
return false;
}
}
}
return true;
}
}
注意:最后要把拦截器加入到配置里面
基本上就是这样了,也可以根据需求再改,关于数据库表业务会需要加上用户组表的信息。
标签:基于,拦截器,角色,RBAC,001,编号,权限,class 来源: https://www.cnblogs.com/sxxs/p/14015464.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。