【sa-token】忽略权限注解不好使

This commit is contained in:
JEECG
2025-10-16 12:36:29 +08:00
parent a250163198
commit 736515f63a

View File

@ -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<ApplicationReadyEvent> {
@Lazy(false)
@Component
@AllArgsConstructor
public class IgnoreAuthPostProcessor implements InitializingBean {
@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
List<String> ignoreAuthList = new ArrayList<>();
// 获取所有的RequestMapping
Map<RequestMappingInfo, HandlerMethod> 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<String> 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<String> 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<String> rebuildUrl(String[] bases, String[] uris) {
List<String> 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;
}
}