diff --git a/continew-webapi/src/main/java/top/continew/admin/config/satoken/SaTokenConfiguration.java b/continew-webapi/src/main/java/top/continew/admin/config/satoken/SaTokenConfiguration.java index 194e4b7e..94c49efd 100644 --- a/continew-webapi/src/main/java/top/continew/admin/config/satoken/SaTokenConfiguration.java +++ b/continew-webapi/src/main/java/top/continew/admin/config/satoken/SaTokenConfiguration.java @@ -17,6 +17,7 @@ package top.continew.admin.config.satoken; import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.interceptor.SaInterceptor; @@ -26,8 +27,14 @@ import cn.dev33.satoken.sign.SaSignUtil; import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpUtil; import lombok.RequiredArgsConstructor; +import org.springframework.aop.framework.AopProxyUtils; +import org.springframework.aop.support.AopUtils; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.AnnotationUtils; import top.continew.admin.common.context.UserContext; import top.continew.admin.common.context.UserContextHolder; import top.continew.admin.open.sign.OpenApiSignTemplate; @@ -35,8 +42,9 @@ import top.continew.starter.auth.satoken.autoconfigure.SaTokenExtensionPropertie import top.continew.starter.core.constant.StringConstants; import top.continew.starter.core.exception.BusinessException; import top.continew.starter.core.validation.CheckUtils; +import top.continew.starter.extension.crud.annotation.CrudRequestMapping; -import java.util.Collection; +import java.util.*; /** * Sa-Token 配置 @@ -52,6 +60,7 @@ public class SaTokenConfiguration { private final SaTokenExtensionProperties properties; private final LoginPasswordProperties loginPasswordProperties; private final OpenApiSignTemplate signTemplate; + private final ApplicationContext applicationContext; /** * Sa-Token 权限认证配置 @@ -90,4 +99,34 @@ public class SaTokenConfiguration { CheckUtils.throwIf(userContext.isPasswordExpired(), "密码已过期,请修改密码"); })); } + + /** + * 配置 sa-token SaIgnore 注解排除路径 + *

主要针对 @CrudRequestMapping 注解

+ */ + @EventListener(ApplicationReadyEvent.class) + public void configureSaTokenExcludes() { + String[] beanNames = applicationContext.getBeanDefinitionNames(); + List additionalExcludes = Arrays.stream(beanNames).parallel().map(beanName -> { + Object bean = applicationContext.getBean(beanName); + Class clazz = bean.getClass(); + if (AopUtils.isAopProxy(bean)) { + clazz = AopProxyUtils.ultimateTargetClass(bean); + } + CrudRequestMapping crudRequestMapping = AnnotationUtils.findAnnotation(clazz, CrudRequestMapping.class); + SaIgnore saIgnore = AnnotationUtils.findAnnotation(clazz, SaIgnore.class); + + if (crudRequestMapping != null && saIgnore != null) { + return crudRequestMapping.value() + "/**"; + } + return null; + }).filter(Objects::nonNull).toList(); + if (!additionalExcludes.isEmpty()) { + // 合并现有的 excludes 和新扫描到的 + List allExcludes = new ArrayList<>(Arrays.asList(properties.getSecurity().getExcludes())); + allExcludes.addAll(additionalExcludes); + // 转回数组 + properties.getSecurity().setExcludes(allExcludes.toArray(new String[0])); + } + } }