RABC 权限拦截设置
1 RABC 是什么?
rabc 是一种用于设计权限的一种思想,流程图如下
2 硬编码实现的思想
RABC 主要有user 用户表,role角色表,权限表,以及role-和user-role的中间关联表,但是实际上对于一般的需求,我们可以只使用user用户表, 里面存储字段标识 角色信息,然后在代码层面进行编码方式 使用enum枚举出所有角色表,使用 权限注解标识方法,将权限注解与方法进行一个绑定,其中权限里面包括(角色)信息,通过拦截器进行拦截权限进行筛选。
/*** rbac 将角色存储到内存里* 权限拦截*/
@LoginRequired
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface PermissionRequired {/*** 角色*/UserType[] userType() default {UserType.VISITOR};/*** 逻辑关系,比如 ADMIN&&TEACHER 或者 ADMIN||TEACHER** @return*/Logical logical();}
/*** 用户角色枚举*/
@Getter
public enum UserType {ADMIN(1,"管理员"),TEACHER(2, "教师"),STUDENT(3, "学生"),VISITOR(4, "游客");private final Integer value;private final String desc;UserType(Integer value,String desc){this.value = value;this.desc = desc;}public static boolean hasPermission(UserType[] userTypes,Integer typeOfUser,Logical logical){Objects.requireNonNull(userTypes);Objects.requireNonNull(logical);// 单角色判断if(userTypes.length==1 && userTypes[0].getValue().equals(typeOfUser)){return true;}// 1.2 要求多个角色权限if (userTypes.length > 1) {// AND:预留,当前设计其实不支持一个用户有多个角色if (Logical.AND.equals(logical)) {return false;}// OR:只要用户拥有其中一个角色即可if (Logical.OR.equals(logical)) {for (UserType type : userTypes) {if (type.getValue().equals(typeOfUser)) {return true;}}}}return false;}}
public class SecurityInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 不拦截跨域请求相关if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {return true;}// 如果方法上没有加@LoginRequired或@PermissionRequired(上面叠加了@LoginRequired),直接放行if (isLoginFree(handler)) {return true;}// 登录校验User user = handleLogin(request, response);ThreadLocalUtil.put(WebConstant.USER_INFO, user);// 权限校验checkPermission(user, handler);// 放行到Controllerreturn super.preHandle(request, response, handler);}
@PermissionRequired(userType = {UserType.ADMIN,UserType.TEACHER}, logical = Logical.OR)@GetMapping("/needPermission")public Result<String> needPermission() {return Result.success("if you see this, you has the permission.");}
缺点: 硬编码 将角色与权限进行的硬编码绑定,无法进行动态修改权限
3 动态实现
在数据库 中创建 五张表