diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaIgnore.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaIgnore.java new file mode 100644 index 00000000..3e31915f --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaIgnore.java @@ -0,0 +1,20 @@ +package cn.dev33.satoken.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 忽略认证:表示被修饰的方法或类无需进行注解认证和路由拦截认证 + * + *

请注意:此注解的忽略效果只针对 SaInterceptor拦截器 和 APO注解鉴权 生效,对自定义拦截器与过滤器不生效

+ * + * @author kong + * @since: 2022-8-21 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface SaIgnore { + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java index 9f8e79d5..eaef034b 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java @@ -15,6 +15,7 @@ import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckRole; import cn.dev33.satoken.annotation.SaCheckSafe; +import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.basic.SaBasicUtil; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.util.SaFoxUtil; @@ -179,6 +180,16 @@ public final class SaStrategy { return element.getAnnotation(annotationClass); }; + /** + * 判断一个 Method 或其所属 Class 是否包含指定注解 + * + *

参数 [Method, 注解] + */ + public BiFunction isAnnotationPresent = (method, annotationClass) -> { + return me.getAnnotation.apply(method, SaIgnore.class) != null || + me.getAnnotation.apply(method.getDeclaringClass(), SaIgnore.class) != null; + }; + /** * 拼接两个url *

例如:url1=http://domain.cn,url2=/sso/auth,则返回:http://domain.cn/sso/auth diff --git a/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java b/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java index 309435e0..92ce5cb6 100644 --- a/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java +++ b/sa-token-plugin/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java @@ -1,5 +1,7 @@ package cn.dev33.satoken.aop; +import java.lang.reflect.Method; + import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -8,6 +10,7 @@ import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.strategy.SaStrategy; import cn.dev33.satoken.util.SaTokenConsts; @@ -54,9 +57,18 @@ public class SaCheckAspect { @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { - // 注解鉴权 + // 获取对应的 Method 处理函数 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); - SaStrategy.me.checkMethodAnnotation.accept(signature.getMethod()); + Method method = signature.getMethod(); + + // 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权 + if(SaStrategy.me.isAnnotationPresent.apply(method, SaIgnore.class)) { + // ... + } else { + // 注解鉴权 + SaStrategy.me.checkMethodAnnotation.accept(method); + } + try { // 执行原有逻辑 diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java index 3889dffa..af60c0d7 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaInterceptor.java @@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; +import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.exception.BackResultException; import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.fun.SaParamFunction; @@ -26,9 +27,6 @@ public class SaInterceptor implements HandlerInterceptor { */ public boolean isAnnotation = true; - - - /** * 认证函数:每次请求执行 *

参数:路由处理函数指针 @@ -84,7 +82,16 @@ public class SaInterceptor implements HandlerInterceptor { // 获取此请求对应的 Method 处理函数 if(handler instanceof HandlerMethod) { Method method = ((HandlerMethod) handler).getMethod(); - SaStrategy.me.checkMethodAnnotation.accept(method); + + // 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权 + if(SaStrategy.me.isAnnotationPresent.apply(method, SaIgnore.class)) { + return true; + } + + // 注解校验 + if(isAnnotation) { + SaStrategy.me.checkMethodAnnotation.accept(method); + } } // Auth 校验