优化MethodUrl

This commit is contained in:
yandanyang 2021-09-26 16:56:40 +08:00
parent 5153558326
commit 5d9a9bef52
3 changed files with 68 additions and 108 deletions

View File

@ -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<String> annotationValueList = SmartSecurityUrl.getAnnotationValueList(method, uriPrefix);
//判断是否被忽略
//URL匹配
AntPathMatcher antPathMatcher = new AntPathMatcher();
antPathMatcher.setCaseSensitive(false);
antPathMatcher.setTrimTokens(true);
//无需验证的URL集合
List<String> noValidUrlList = smartSecurityUrlMatchers.getNoValidUrl();
if (this.contain(antPathMatcher, noValidUrlList, annotationValueList)) {
//获取方法的请求路径
Set<String> methodUrl = smartSecurityUrlMatchers.getMethodUrl(method);
if (this.contain(antPathMatcher, noValidUrlList, methodUrl)) {
return super.getAttributes(method, targetClass);
}
ArrayList<ConfigAttribute> configAttributes = new ArrayList(1);
@ -101,13 +97,13 @@ public class SmartSecurityMetadataSource extends PrePostAnnotationSecurityMetada
return configAttributes;
}
public Boolean contain(AntPathMatcher antPathMatcher, List<String> ignores, List<String> valueList) {
public Boolean contain(AntPathMatcher antPathMatcher, List<String> ignores, Set<String> 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;
}
}

View File

@ -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<String> getAnnotationValueList(Method method, String uriPrefix) {
List<String> 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<String> uriList(String uriPrefix, String[] values) {
List<String> uriList = Lists.newArrayList();
for (String uri : values) {
uriList.add(uriPrefix + uri);
}
return uriList;
}
}

View File

@ -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<String> authenticatedUrl = Lists.newArrayList();
/**
* 方法的请求路径
*/
private Map<Method, Set<String>> methodUrlMap = new HashMap<>();
/**
* 获取忽略的URL集合
*
* @return
*/
public List<String> getIgnoreUrl() {
public synchronized List<String> 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<String> getAuthenticatedUrlList() {
public synchronized List<String> 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<String> getAnonymousUrl() {
private synchronized List<String> getAnonymousUrl() {
if (CollectionUtils.isNotEmpty(anonymousUrl)) {
return anonymousUrl;
}
Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(scanPackage)).setScanners(new MethodAnnotationsScanner()));
Set<Method> methodSet = reflections.getMethodsAnnotatedWith(NoNeedLogin.class);
for (Method method : methodSet) {
String uriPrefix = SmartSecurityUrl.getUriPrefix(method);
List<String> valueList = SmartSecurityUrl.getAnnotationValueList(method, uriPrefix);
anonymousUrl.addAll(valueList);
Map<Method, Set<String>> methodSetMap = this.getMethodUrlMap();
for (Entry<Method, Set<String>> 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<Method, Set<String>> getMethodUrlMap() {
if (MapUtils.isNotEmpty(methodUrlMap)) {
return methodUrlMap;
}
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
//获取url与类和方法的对应信息
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
for (Entry<RequestMappingInfo, HandlerMethod> entry : map.entrySet()) {
RequestMappingInfo requestMappingInfo = entry.getKey();
Set<String> urls = requestMappingInfo.getPatternsCondition().getPatterns();
if (CollectionUtils.isEmpty(urls)) {
continue;
}
HandlerMethod handlerMethod = entry.getValue();
methodUrlMap.put(handlerMethod.getMethod(), urls);
}
return methodUrlMap;
}
public Set<String> getMethodUrl(Method method) {
return methodUrlMap.get(method);
}
/**
* 获取需要校验的包路径
*
* @return
*/
public String getValidPackage() {