diff --git a/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityMetadataSource.java b/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityMetadataSource.java index 3dfa34d7..d0b34f83 100644 --- a/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityMetadataSource.java +++ b/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityMetadataSource.java @@ -11,10 +11,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * 此类用于默认给所有接口添加权限 @privilegeCheck.checkPermission('%s') @@ -75,16 +72,15 @@ public class SmartSecurityMetadataSource extends PrePostAnnotationSecurityMetada if (postAuthorize != null) { return super.getAttributes(method, targetClass); } - //获取注解值 - String uriPrefix = SmartSecurityUrl.getUriPrefix(method); - List annotationValueList = SmartSecurityUrl.getAnnotationValueList(method, uriPrefix); - //判断是否被忽略 + //URL匹配 AntPathMatcher antPathMatcher = new AntPathMatcher(); antPathMatcher.setCaseSensitive(false); antPathMatcher.setTrimTokens(true); //无需验证的URL集合 List noValidUrlList = smartSecurityUrlMatchers.getNoValidUrl(); - if (this.contain(antPathMatcher, noValidUrlList, annotationValueList)) { + //获取方法的请求路径 + Set methodUrl = smartSecurityUrlMatchers.getMethodUrl(method); + if (this.contain(antPathMatcher, noValidUrlList, methodUrl)) { return super.getAttributes(method, targetClass); } ArrayList configAttributes = new ArrayList(1); @@ -101,13 +97,13 @@ public class SmartSecurityMetadataSource extends PrePostAnnotationSecurityMetada return configAttributes; } - public Boolean contain(AntPathMatcher antPathMatcher, List ignores, List valueList) { + public Boolean contain(AntPathMatcher antPathMatcher, List ignores, Set urls) { if (CollectionUtils.isEmpty(ignores)) { return false; } for (String ignoreUrl : ignores) { - for (String uri : valueList) { - if (antPathMatcher.match(ignoreUrl, uri)) { + for (String url : urls) { + if (antPathMatcher.match(ignoreUrl, url)) { return true; } } diff --git a/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityUrl.java b/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityUrl.java deleted file mode 100644 index a53d6c97..00000000 --- a/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityUrl.java +++ /dev/null @@ -1,80 +0,0 @@ -package net.lab1024.smartadmin.service.common.security; - -import com.google.common.collect.Lists; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; - -import java.lang.reflect.Method; -import java.util.List; - -/** - * [ ] - * - * @author 罗伊 - * @date 2021/8/31 11:30 - */ -public class SmartSecurityUrl { - - /** - * 获取指定方法的uri 前缀 - * 即controller层注解 - * - * @param method - * @return - */ - public static String getUriPrefix(Method method) { - Class clazz = method.getDeclaringClass(); - return getUriPrefix(clazz); - } - - - public static String getUriPrefix(Class clazz) { - String uriPrefix = ""; - RequestMapping classRequestMapping = (RequestMapping) clazz.getAnnotation(RequestMapping.class); - if (classRequestMapping != null) { - uriPrefix = classRequestMapping.value()[0]; - } - Class superclass = clazz.getSuperclass(); - if (superclass == null || superclass == Object.class) { - return uriPrefix; - } - RequestMapping superClassRequestMapping = (RequestMapping) superclass.getAnnotation(RequestMapping.class); - if (superClassRequestMapping != null) { - uriPrefix = superClassRequestMapping.value()[0] + uriPrefix; - } - return uriPrefix; - } - - /** - * 获取完整的uri前缀 - * - * @param method - * @param uriPrefix - * @return - */ - public static List getAnnotationValueList(Method method, String uriPrefix) { - List valueList = Lists.newArrayList(); - GetMapping getMapping = method.getAnnotation(GetMapping.class); - if (getMapping != null) { - valueList.addAll(uriList(uriPrefix, getMapping.value())); - } - PostMapping postMapping = method.getAnnotation(PostMapping.class); - if (postMapping != null) { - valueList.addAll(uriList(uriPrefix, postMapping.value())); - } - RequestMapping requestMapping = method.getAnnotation(RequestMapping.class); - if (requestMapping != null) { - valueList.addAll(uriList(uriPrefix, requestMapping.value())); - } - return valueList; - } - - public static List uriList(String uriPrefix, String[] values) { - List uriList = Lists.newArrayList(); - for (String uri : values) { - uriList.add(uriPrefix + uri); - } - return uriList; - } -} diff --git a/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityUrlMatchers.java b/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityUrlMatchers.java index da0e1646..a4b3daae 100644 --- a/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityUrlMatchers.java +++ b/admin-api/java-api/src/main/java/net/lab1024/smartadmin/service/common/security/SmartSecurityUrlMatchers.java @@ -5,15 +5,20 @@ import lombok.extern.slf4j.Slf4j; import net.lab1024.smartadmin.service.common.anno.NoNeedLogin; import net.lab1024.smartadmin.service.common.constant.CommonConst; import org.apache.commons.collections4.CollectionUtils; -import org.reflections.Reflections; -import org.reflections.scanners.MethodAnnotationsScanner; -import org.reflections.util.ClasspathHelper; -import org.reflections.util.ConfigurationBuilder; +import org.apache.commons.collections4.MapUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.lang.reflect.Method; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; /** @@ -29,6 +34,9 @@ public class SmartSecurityUrlMatchers { @Value("${project.module}") private String scanPackage; + @Autowired + private WebApplicationContext applicationContext; + /** * 匿名访问URL */ @@ -43,12 +51,17 @@ public class SmartSecurityUrlMatchers { */ private List authenticatedUrl = Lists.newArrayList(); + /** + * 方法的请求路径 + */ + private Map> methodUrlMap = new HashMap<>(); + /** * 获取忽略的URL集合 * * @return */ - public List getIgnoreUrl() { + public synchronized List getIgnoreUrl() { if (CollectionUtils.isNotEmpty(ignoreUrl)) { return ignoreUrl; } @@ -57,7 +70,7 @@ public class SmartSecurityUrlMatchers { ignoreUrl.add("/webjars/**"); ignoreUrl.add("/*/api-docs"); ignoreUrl.add(CommonConst.ApiUrl.API_PREFIX_SUPPORT + "/**"); - log.info("忽略URL:{}",ignoreUrl); + log.info("忽略URL:{}", ignoreUrl); return ignoreUrl; } @@ -66,12 +79,12 @@ public class SmartSecurityUrlMatchers { * * @return */ - public List getAuthenticatedUrlList() { + public synchronized List getAuthenticatedUrlList() { if (CollectionUtils.isNotEmpty(authenticatedUrl)) { return authenticatedUrl; } authenticatedUrl.add("/admin/**"); - log.info("认证URL:{}",authenticatedUrl); + log.info("认证URL:{}", authenticatedUrl); return authenticatedUrl; } @@ -80,23 +93,54 @@ public class SmartSecurityUrlMatchers { * * @return */ - private List getAnonymousUrl() { + private synchronized List getAnonymousUrl() { if (CollectionUtils.isNotEmpty(anonymousUrl)) { return anonymousUrl; } - Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(scanPackage)).setScanners(new MethodAnnotationsScanner())); - Set methodSet = reflections.getMethodsAnnotatedWith(NoNeedLogin.class); - for (Method method : methodSet) { - String uriPrefix = SmartSecurityUrl.getUriPrefix(method); - List valueList = SmartSecurityUrl.getAnnotationValueList(method, uriPrefix); - anonymousUrl.addAll(valueList); + Map> methodSetMap = this.getMethodUrlMap(); + for (Entry> entry : methodSetMap.entrySet()) { + Method method = entry.getKey(); + NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class); + if (null == noNeedLogin) { + continue; + } + anonymousUrl.addAll(entry.getValue()); } - log.info("匿名URL:{}",anonymousUrl); + log.info("匿名URL:{}", anonymousUrl); return anonymousUrl; } + /** + * 获取每个方法的请求路径 + * + * @return + */ + private synchronized Map> getMethodUrlMap() { + if (MapUtils.isNotEmpty(methodUrlMap)) { + return methodUrlMap; + } + RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); + //获取url与类和方法的对应信息 + Map map = mapping.getHandlerMethods(); + for (Entry entry : map.entrySet()) { + RequestMappingInfo requestMappingInfo = entry.getKey(); + Set urls = requestMappingInfo.getPatternsCondition().getPatterns(); + if (CollectionUtils.isEmpty(urls)) { + continue; + } + HandlerMethod handlerMethod = entry.getValue(); + methodUrlMap.put(handlerMethod.getMethod(), urls); + } + return methodUrlMap; + } + + public Set getMethodUrl(Method method) { + return methodUrlMap.get(method); + } + /** * 获取需要校验的包路径 + * * @return */ public String getValidPackage() {