SpringBoot中如何创建自定义注解实现权限角色控制?

2026-05-22 07:021阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计929个文字,预计阅读时间需要4分钟。

SpringBoot中如何创建自定义注解实现权限角色控制?

================================

©Copyright 蕃薯耀2022-04-25

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() {}

(时间宝贵,分享不易,捐赠回馈,^_^)

SpringBoot中如何创建自定义注解实现权限角色控制?

================================

©Copyright 蕃薯耀2022-04-25

www.cnblogs.com/fanshuyao/

今天越懒,明天要做的事越多。

本文共计929个文字,预计阅读时间需要4分钟。

SpringBoot中如何创建自定义注解实现权限角色控制?

================================

©Copyright 蕃薯耀2022-04-25

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() {}

(时间宝贵,分享不易,捐赠回馈,^_^)

SpringBoot中如何创建自定义注解实现权限角色控制?

================================

©Copyright 蕃薯耀2022-04-25

www.cnblogs.com/fanshuyao/

今天越懒,明天要做的事越多。