================================ ©Copyright 蕃薯耀2022-04-25 https://www.cnblogs.com/fanshuyao/ 一、自定义角色注解 import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Ret
================================
©Copyright 蕃薯耀 2022-04-25
https://www.cnblogs.com/fanshuyao/
一、自定义角色注解
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface HasRoles { String[] value() default {}; HasType hasType() default HasType.OR; //跳过检查,当类有注解,而类中某个方法不需要校验时,可以设置为true跳过检查 boolean skipCheck() default false; }
二、自定义角色注解AOP
import java.lang.reflect.Method; import javax.annotation.Resource; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import com.zj31mep.biz.system.annotation.HasRoles; import com.zj31mep.biz.system.annotation.HasType; import com.zj31mep.biz.system.service.SysRoleService; import com.zj31mep.exception.BizException; import com.zj31mep.utils.ContextUtil; import com.zj31mep.utils.RequestUtils; @Component @Aspect public class HasRoleAop { private static final Logger log = LoggerFactory.getLogger(HasRoleAop.class); @Resource private SysRoleService sysRoleService; private final static String POINT_CUT = "pointCut()"; //@annotation:用于匹配当前执行方法持有指定注解的方法 //@within:用于匹配所有持有指定注解类型内的方法:target.getClass().equals(within表达式中指定的类型) //@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解 //execution:用于匹配方法执行的连接点 //@within和@target针对类的注解,@annotation是针对方法的注解 //使用: //@Pointcut(value = "@within(com.zj31mep.biz.system.annotation.HasRoles) || @annotation(com.zj31mep.biz.system.annotation.HasRoles)") //@Pointcut(value = "@annotation(com.zj31mep.biz.system.annotation.HasRoles) && @annotation(hasRoles)") //@within不能注入@annotation(hasRoles),不然@within会失效,获取注解通过反射 //@annotation:只使用@annotation,能注入注解对象,如下: /* * @Around(value = "@annotation(com.zj31mep.biz.system.annotation.HasRoles) && @annotation(hasRoles)", argNames="hasRoles") * public Object around(ProceedingJoinPoint proceedingJoinPoint, HasRoles hasRoles) throws Throwable { */ //@Pointcut("@annotation(com.zj31mep.biz.system.annotation.HasRoles)") @Pointcut(value = "@within(com.zj31mep.biz.system.annotation.HasRoles) " + "|| @annotation(com.zj31mep.biz.system.annotation.HasRoles)") public void pointCut() {} @Around(value = POINT_CUT) public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //log.info("proceedingJoinPoint = {}", proceedingJoinPoint); HasRoles hasRoles = null; Method targetMethod = getMethod(proceedingJoinPoint); if(targetMethod.isAnnotationPresent(HasRoles.class)){ hasRoles = getMethodAnnotation(proceedingJoinPoint); }else { hasRoles = getClassAnnotation(proceedingJoinPoint); } if(hasRoles.skipCheck()) { return proceedingJoinPoint.proceed(); } String[] values = hasRoles.value(); if(values == null || values.length < 1) { BizException.error("@HasRoles value不能为空"); } HasType hasType = hasRoles.hasType(); if(!sysRoleService.hasRoleByRedis(values, hasType)) { //BizException.error("无权限访问"); log.error("用户无权限访问Url:{} ,用户:{}", RequestUtils.getUrl(false), ContextUtil.getUser()); return RequestUtils.response403(); } return proceedingJoinPoint.proceed(); } private Method getMethod(ProceedingJoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); return methodSignature.getMethod(); } private HasRoles getMethodAnnotation(ProceedingJoinPoint joinPoint) throws NoSuchMethodException { Method method = getMethod(joinPoint); return method.getAnnotation(HasRoles.class); } private HasRoles getClassAnnotation(ProceedingJoinPoint joinPoint) { return AnnotationUtils.findAnnotation(joinPoint.getTarget().getClass(), HasRoles.class); } }
@within和@target针对类的注解,@annotation是针对方法的注解
@annotation:用于匹配当前执行方法持有指定注解的方法
@within:用于匹配所有持有指定注解类型内的方法:target.getClass().equals(within表达式中指定的类型)
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解
execution:用于匹配方法执行的连接点
@within和@target的区别,主要是在继承中存在区别
三、@HasRoles角色注解使用
方法上的注解优先于类上的注解,当类、方法同时有注解时,方法的注解生效,类的注解不生效。
1、在类上使用
@HasRoles({Role.ADMIN, Role.SUPER_ADMIN})
@HasRoles({Role.ADMIN, Role.SUPER_ADMIN}) public class SysDictController {}
2、在方法上使用
@HasRoles(value = Role.SUPER_ADMIN)
@HasRoles(value = Role.SUPER_ADMIN) @RequestMapping("/add") public ModelAndView add() {}
3、跳过检查
@HasRoles(skipCheck = true)
@HasRoles(skipCheck = true) @RequestMapping("/select") public ModelAndView select() {}
(时间宝贵,分享不易,捐赠回馈,^_^)
================================
©Copyright 蕃薯耀 2022-04-25
https://www.cnblogs.com/fanshuyao/
今天越懒,明天要做的事越多。