From 736515f63a2df2067beaf7447e9d39b9c8dc933f Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Thu, 16 Oct 2025 12:36:29 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90sa-token=E3=80=91=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=B3=A8=E8=A7=A3=E4=B8=8D=E5=A5=BD=E4=BD=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ignore/IgnoreAuthPostProcessor.java | 118 +++++++++++++----- 1 file changed, 84 insertions(+), 34 deletions(-) diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/satoken/ignore/IgnoreAuthPostProcessor.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/satoken/ignore/IgnoreAuthPostProcessor.java index 08592444f..498c8bca6 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/satoken/ignore/IgnoreAuthPostProcessor.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/satoken/ignore/IgnoreAuthPostProcessor.java @@ -1,54 +1,104 @@ package org.jeecg.config.satoken.ignore; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jeecg.config.satoken.IgnoreAuth; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.lang.reflect.Method; +import java.util.*; +import java.util.stream.Collectors; /** - * 扫描@IgnoreAuth注解的url,存储到内存中 + * 在spring boot初始化时,根据@RestController注解获取当前spring容器中的bean * @author eightmonth - * @date 2024/4/18 15:09 + * @date 2024/4/18 11:35 */ -@Component @Slf4j -public class IgnoreAuthPostProcessor implements ApplicationListener { +@Lazy(false) +@Component +@AllArgsConstructor +public class IgnoreAuthPostProcessor implements InitializingBean { - @Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping; + @Override - public void onApplicationEvent(ApplicationReadyEvent event) { - List ignoreAuthList = new ArrayList<>(); - - // 获取所有的RequestMapping - Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); - - handlerMethods.forEach((mapping, handlerMethod) -> { - // 获取方法上的@IgnoreAuth注解 - IgnoreAuth ignoreAuth = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), IgnoreAuth.class); - - if (ignoreAuth != null && mapping.getPathPatternsCondition() != null) { - // 获取路径模式 - mapping.getPathPatternsCondition().getPatterns().forEach(pattern -> { - String path = pattern.getPatternString(); - ignoreAuthList.add(path); + public void afterPropertiesSet() throws Exception { + + long startTime = System.currentTimeMillis(); + + List ignoreAuthUrls = new ArrayList<>(); + + // 优化:直接从HandlerMethod过滤,避免重复扫描 + requestMappingHandlerMapping.getHandlerMethods().values().stream() + .filter(handlerMethod -> handlerMethod.getMethod().isAnnotationPresent(IgnoreAuth.class)) + .forEach(handlerMethod -> { + Class clazz = handlerMethod.getBeanType(); + Method method = handlerMethod.getMethod(); + ignoreAuthUrls.addAll(processIgnoreAuthMethod(clazz, method)); }); + + log.info("Init Token ignoreAuthUrls Config [ 集合 ] :{}", ignoreAuthUrls); + if (!CollectionUtils.isEmpty(ignoreAuthUrls)) { + InMemoryIgnoreAuth.set(ignoreAuthUrls); + } + + // 计算方法的耗时 + long endTime = System.currentTimeMillis(); + long elapsedTime = endTime - startTime; + log.info("Init Token ignoreAuthUrls Config [ 耗时 ] :" + elapsedTime + "ms"); + } + + // 优化:新方法处理单个@IgnoreAuth方法,减少重复注解检查 + private List processIgnoreAuthMethod(Class clazz, Method method) { + RequestMapping base = clazz.getAnnotation(RequestMapping.class); + String[] baseUrl = Objects.nonNull(base) ? base.value() : new String[]{}; + + String[] uri = null; + if (method.isAnnotationPresent(RequestMapping.class)) { + uri = method.getAnnotation(RequestMapping.class).value(); + } else if (method.isAnnotationPresent(GetMapping.class)) { + uri = method.getAnnotation(GetMapping.class).value(); + } else if (method.isAnnotationPresent(PostMapping.class)) { + uri = method.getAnnotation(PostMapping.class).value(); + } else if (method.isAnnotationPresent(PutMapping.class)) { + uri = method.getAnnotation(PutMapping.class).value(); + } else if (method.isAnnotationPresent(DeleteMapping.class)) { + uri = method.getAnnotation(DeleteMapping.class).value(); + } else if (method.isAnnotationPresent(PatchMapping.class)) { + uri = method.getAnnotation(PatchMapping.class).value(); + } + + return uri != null ? rebuildUrl(baseUrl, uri) : Collections.emptyList(); + } + + private List rebuildUrl(String[] bases, String[] uris) { + List urls = new ArrayList<>(); + if (bases.length > 0) { + for (String base : bases) { + for (String uri : uris) { + // 如果uri包含路径占位符, 则需要将其替换为* + if (uri.matches(".*\\{.*}.*")) { + uri = uri.replaceAll("\\{.*?}", "*"); + } + urls.add(prefix(base) + prefix(uri)); + } } - }); - - InMemoryIgnoreAuth.set(ignoreAuthList); - log.info("Sa-Token 免认证路径加载完成,共{}条: {}", ignoreAuthList.size(), ignoreAuthList); + } else { + Arrays.stream(uris).forEach(uri -> { + urls.add(prefix(uri)); + }); + } + return urls; + } + + private String prefix(String seg) { + return seg.startsWith("/") ? seg : "/"+seg; } } -