1717package top .continew .admin .config .satoken ;
1818
1919import cn .dev33 .satoken .SaManager ;
20+ import cn .dev33 .satoken .annotation .SaIgnore ;
2021import cn .dev33 .satoken .context .SaHolder ;
2122import cn .dev33 .satoken .context .model .SaRequest ;
2223import cn .dev33 .satoken .interceptor .SaInterceptor ;
2627import cn .dev33 .satoken .stp .StpInterface ;
2728import cn .dev33 .satoken .stp .StpUtil ;
2829import lombok .RequiredArgsConstructor ;
30+ import org .springframework .aop .framework .AopProxyUtils ;
31+ import org .springframework .aop .support .AopUtils ;
32+ import org .springframework .boot .context .event .ApplicationReadyEvent ;
33+ import org .springframework .context .ApplicationContext ;
2934import org .springframework .context .annotation .Bean ;
3035import org .springframework .context .annotation .Configuration ;
36+ import org .springframework .context .event .EventListener ;
37+ import org .springframework .core .annotation .AnnotationUtils ;
3138import top .continew .admin .common .context .UserContext ;
3239import top .continew .admin .common .context .UserContextHolder ;
3340import top .continew .admin .open .sign .OpenApiSignTemplate ;
3441import top .continew .starter .auth .satoken .autoconfigure .SaTokenExtensionProperties ;
3542import top .continew .starter .core .constant .StringConstants ;
3643import top .continew .starter .core .exception .BusinessException ;
3744import top .continew .starter .core .validation .CheckUtils ;
45+ import top .continew .starter .extension .crud .annotation .CrudRequestMapping ;
3846
39- import java .util .Collection ;
47+ import java .util .* ;
4048
4149/**
4250 * Sa-Token 配置
@@ -52,6 +60,7 @@ public class SaTokenConfiguration {
5260 private final SaTokenExtensionProperties properties ;
5361 private final LoginPasswordProperties loginPasswordProperties ;
5462 private final OpenApiSignTemplate signTemplate ;
63+ private final ApplicationContext applicationContext ;
5564
5665 /**
5766 * Sa-Token 权限认证配置
@@ -90,4 +99,34 @@ public SaInterceptor saInterceptor() {
9099 CheckUtils .throwIf (userContext .isPasswordExpired (), "密码已过期,请修改密码" );
91100 }));
92101 }
102+
103+ /**
104+ * 配置 sa-token SaIgnore 注解排除路径
105+ * <p>主要针对 @CrudRequestMapping 注解</p>
106+ */
107+ @ EventListener (ApplicationReadyEvent .class )
108+ public void configureSaTokenExcludes () {
109+ String [] beanNames = applicationContext .getBeanDefinitionNames ();
110+ List <String > additionalExcludes = Arrays .stream (beanNames ).parallel ().map (beanName -> {
111+ Object bean = applicationContext .getBean (beanName );
112+ Class <?> clazz = bean .getClass ();
113+ if (AopUtils .isAopProxy (bean )) {
114+ clazz = AopProxyUtils .ultimateTargetClass (bean );
115+ }
116+ CrudRequestMapping crudRequestMapping = AnnotationUtils .findAnnotation (clazz , CrudRequestMapping .class );
117+ SaIgnore saIgnore = AnnotationUtils .findAnnotation (clazz , SaIgnore .class );
118+
119+ if (crudRequestMapping != null && saIgnore != null ) {
120+ return crudRequestMapping .value () + "/**" ;
121+ }
122+ return null ;
123+ }).filter (Objects ::nonNull ).toList ();
124+ if (!additionalExcludes .isEmpty ()) {
125+ // 合并现有的 excludes 和新扫描到的
126+ List <String > allExcludes = new ArrayList <>(Arrays .asList (properties .getSecurity ().getExcludes ()));
127+ allExcludes .addAll (additionalExcludes );
128+ // 转回数组
129+ properties .getSecurity ().setExcludes (allExcludes .toArray (new String [0 ]));
130+ }
131+ }
93132}
0 commit comments