4.在切入的方法体里写上权限判断的逻辑
等
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface PreAuth { /** * * 堆代码 duidaima.com * permissionAll()-----只要配置了角色就可以访问 * hasPermission("MENU.QUERY")-----有MENU.QUERY操作权限的角色可以访问 * permitAll()-----放行所有请求 * denyAll()-----只有超级管理员角色才可访问 * hasAuth()-----只有登录后才可访问 * hasTimeAuth(1,,10)-----只有在1-10点间访问 * hasRole(‘管理员’)-----具有管理员角色的人才能访问 * hasAllRole(‘管理员’,'总工程师')-----同时具有管理员、总工程师角色的人才能访问 * * Spring el * 文档地址:https://docs.spring.io/spring/docs/5.1.6.RELEASE/spring-framework-reference/core.html#expressions */ String value(); }定义切面
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();然后,从注解上获取我们需要的表达式:
MethodSignature ms = point.getSignature() instanceof MethodSignature? (MethodSignature) point.getSignature():null; Method method = ms.getMethod(); // 读取权限注解,优先方法上,没有则读取类 PreAuth preAuth = ClassUtil.getAnnotation(method, PreAuth.class); // 判断表达式 String condition = preAuth.value(); if (StringUtil.isNotBlank(condition)) { //TODU 表达式解析 }表达式解析
private boolean handleAuth(ProceedingJoinPoint point) { MethodSignature ms = point.getSignature() instanceof MethodSignature? (MethodSignature) point.getSignature():null; Method method = ms.getMethod(); // 读取权限注解,优先方法上,没有则读取类 PreAuth preAuth = ClassUtil.getAnnotation(method, PreAuth.class); // 判断表达式 String condition = preAuth.value(); if (StringUtil.isNotBlank(condition)) { Expression expression = EXPRESSION_PARSER.parseExpression(condition); // 方法参数值 Object[] args = point.getArgs(); StandardEvaluationContext context = getEvaluationContext(method, args); //获取解析计算的结果 return expression.getValue(context, Boolean.class); } return false; } /** * 获取方法上的参数 * * @param method 方法 * @param args 变量 * @return {SimpleEvaluationContext} */ private StandardEvaluationContext getEvaluationContext(Method method, Object[] args) { // 初始化Sp el表达式上下文,并设置 AuthFun StandardEvaluationContext context = new StandardEvaluationContext(new AuthFun()); // 设置表达式支持spring bean context.setBeanResolver(new BeanFactoryResolver(applicationContext)); for (int i = 0; i < args.length; i++) { // 读取方法参数 MethodParameter methodParam = ClassUtil.getMethodParameter(method, i); // 设置方法 参数名和值 为spel变量 context.setVariable(methodParam.getParameterName(), args[i]); } return context; }自定义解析方法
public class AuthFun { /** * 判断角色是否具有接口权限 * * @return {boolean} */ public boolean permissionAll() { //TODO } /** * 判断角色是否具有接口权限 * * @param permission 权限编号,对应菜单的MENU_CODE * @return {boolean} */ public boolean hasPermission(String permission) { //TODO } /** * 放行所有请求 * * @return {boolean} */ public boolean permitAll() { return true; } /** * 只有超管角色才可访问 * * @return {boolean} */ public boolean denyAll() { return hasRole(RoleConstant.ADMIN); } /** * 是否已授权 * * @return {boolean} */ public boolean hasAuth() { if(Func.isEmpty(AuthUtil.getUser())){ // TODO 返回异常提醒 }else{ return true; } } /** * 是否有时间授权 * * @param start 开始时间 * @param end 结束时间 * @return {boolean} */ public boolean hasTimeAuth(Integer start, Integer end) { Integer hour = DateUtil.hour(); return hour >= start && hour <= end; } /** * 判断是否有该角色权限 * * @param role 单角色 * @return {boolean} */ public boolean hasRole(String role) { return hasAnyRole(role); } /** * 判断是否具有所有角色权限 * * @param role 角色集合 * @return {boolean} */ public boolean hasAllRole(String... role) { for (String r : role) { if (!hasRole(r)) { return false; } } return true; } /** * 判断是否有该角色权限 * * @param role 角色集合 * @return {boolean} */ public boolean hasAnyRole(String... role) { //获取当前登录用户 BladeUser user = AuthUtil.getUser(); if (user == null) { return false; } String userRole = user.getRoleName(); if (StringUtil.isBlank(userRole)) { return false; } String[] roles = Func.toStrArray(userRole); for (String r : role) { if (CollectionUtil.contains(roles, r)) { return true; } } return false; } }实际使用
@PreAuth("hasPermission('LM_QUERY,LM_QUERY_ALL')") public T 接口名称....原理