Skip to content

Commit

Permalink
Merge pull request #72 from yinjihuan/encrypt1.2.2
Browse files Browse the repository at this point in the history
Encrypt1.2.2
  • Loading branch information
yinjihuan authored Mar 30, 2021
2 parents f8cbd3d + 15ababe commit ed537ff
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 86 deletions.
10 changes: 8 additions & 2 deletions monkey-api-encrypt-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.cxytiandi</groupId>
<artifactId>monkey-api-encrypt-core</artifactId>
<version>1.2.1.RELEASE</version>
<version>1.2.2.RELEASE</version>
<packaging>jar</packaging>

<name>monkey-api-encrypt-core</name>
Expand Down Expand Up @@ -109,7 +109,13 @@
<version>2.0.6.RELEASE</version>
<scope>provided</scope>
</dependency>
</dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.4</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.cxytiandi.encrypt.core;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
Expand All @@ -16,14 +13,20 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.cxytiandi.encrypt.util.RequestUriUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cxytiandi.encrypt.algorithm.AesEncryptAlgorithm;
import com.cxytiandi.encrypt.algorithm.EncryptAlgorithm;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;

/**
* 数据加解密过滤器
Expand All @@ -38,6 +41,8 @@ public class EncryptionFilter implements Filter {

private EncryptAlgorithm encryptAlgorithm = new AesEncryptAlgorithm();

private DispatcherServlet dispatcherServlet;

public EncryptionFilter() {
this.encryptionConfig = new EncryptionConfig();
}
Expand All @@ -46,9 +51,15 @@ public EncryptionFilter(EncryptionConfig config) {
this.encryptionConfig = config;
}

public EncryptionFilter(EncryptionConfig config, EncryptAlgorithm encryptAlgorithm) {
public EncryptionFilter(EncryptionConfig config, DispatcherServlet dispatcherServlet) {
this.encryptionConfig = config;
this.dispatcherServlet = dispatcherServlet;
}

public EncryptionFilter(EncryptionConfig config, EncryptAlgorithm encryptAlgorithm, DispatcherServlet dispatcherServlet) {
this.encryptionConfig = config;
this.encryptAlgorithm = encryptAlgorithm;
this.dispatcherServlet = dispatcherServlet;
}

public EncryptionFilter(String key) {
Expand All @@ -62,6 +73,8 @@ public EncryptionFilter(String key, List<String> responseEncryptUriList, List<St
this.encryptionConfig = new EncryptionConfig(key, responseEncryptUriList, requestDecryptUriList, responseCharset, debug);
}

private AntPathMatcher antPathMatcher = new AntPathMatcher();

@Override
public void init(FilterConfig filterConfig) throws ServletException {

Expand All @@ -82,10 +95,10 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
return;
}

boolean decryptionStatus = this.contains(encryptionConfig.getRequestDecryptUriList(), uri, req.getMethod());
boolean encryptionStatus = this.contains(encryptionConfig.getResponseEncryptUriList(), uri, req.getMethod());
boolean decryptionIgnoreStatus = this.contains(encryptionConfig.getRequestDecryptUriIgnoreList(), uri, req.getMethod());
boolean encryptionIgnoreStatus = this.contains(encryptionConfig.getResponseEncryptUriIgnoreList(), uri, req.getMethod());
boolean decryptionStatus = this.contains(encryptionConfig.getRequestDecryptUriList(), uri, req.getMethod(), req);
boolean encryptionStatus = this.contains(encryptionConfig.getResponseEncryptUriList(), uri, req.getMethod(), req);
boolean decryptionIgnoreStatus = this.contains(encryptionConfig.getRequestDecryptUriIgnoreList(), uri, req.getMethod(), req);
boolean encryptionIgnoreStatus = this.contains(encryptionConfig.getResponseEncryptUriIgnoreList(), uri, req.getMethod(), req);

// 没有配置具体加解密的URI默认全部都开启加解密
if (CollectionUtils.isEmpty(encryptionConfig.getRequestDecryptUriList())
Expand Down Expand Up @@ -205,7 +218,7 @@ private void writeEncryptContent(String responseData, ServletResponse response)
}
}

private boolean contains(List<String> list, String uri, String methodType) {
private boolean contains(List<String> list, String uri, String methodType, HttpServletRequest request) {
if (list.contains(uri)) {
return true;
}
Expand All @@ -214,9 +227,51 @@ private boolean contains(List<String> list, String uri, String methodType) {
if (list.contains(prefixUri)) {
return true;
}

// 优先用AntPathMatcher,其实用这个也够了,底层是一样的,下面用的方式兜底
for (String u : list) {
boolean match = antPathMatcher.match(u, prefixUri);
if (match) {
return true;
}
}

try {
// 支持RestFul风格API
// 采用Spring MVC内置的匹配方式将当前请求匹配到对应的Controller Method上,获取注解进行匹配是否要加解密
HandlerExecutionChain handler = getHandler(request);
if (Objects.isNull(handler)) {
return false;
}

if (Objects.nonNull(handler.getHandler()) && handler.getHandler() instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler.getHandler();
String apiUri = RequestUriUtils.getApiUri(handlerMethod.getClass(), handlerMethod.getMethod(), request.getContextPath());
if (list.contains(apiUri)) {
return true;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return false;
}

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (Objects.isNull(dispatcherServlet)) {
return null;
}
if (dispatcherServlet.getHandlerMappings() != null) {
for (HandlerMapping mapping : dispatcherServlet.getHandlerMappings()) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}

@Override
public void destroy() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.cxytiandi.encrypt.core.EncryptionConfig;
import com.cxytiandi.encrypt.core.EncryptionFilter;
import com.cxytiandi.encrypt.springboot.init.ApiEncryptDataInit;
import org.springframework.web.servlet.DispatcherServlet;


/**
Expand All @@ -30,6 +31,12 @@ public class EncryptAutoConfiguration {
@Autowired(required = false)
private EncryptAlgorithm encryptAlgorithm;

/**
* 用于解决@PathVariable风格的URI
*/
@Autowired(required = false)
private DispatcherServlet dispatcherServlet;

/**
* 不要用泛型注册Filter,泛型在Spring Boot 2.x版本中才有
*
Expand All @@ -40,9 +47,9 @@ public class EncryptAutoConfiguration {
public FilterRegistrationBean filterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
if (encryptAlgorithm != null) {
registration.setFilter(new EncryptionFilter(encryptionConfig, encryptAlgorithm));
registration.setFilter(new EncryptionFilter(encryptionConfig, encryptAlgorithm, dispatcherServlet));
} else {
registration.setFilter(new EncryptionFilter(encryptionConfig));
registration.setFilter(new EncryptionFilter(encryptionConfig, dispatcherServlet));
}
registration.addUrlPatterns(encryptionConfig.getUrlPatterns());
registration.setName("EncryptionFilter");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.lang.reflect.Method;
import java.util.*;

import com.cxytiandi.encrypt.util.RequestUriUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
Expand Down Expand Up @@ -108,7 +109,7 @@ private void initData(Map<String, Object> beanMap) {
// 注解中的URI优先级高
String uri = encrypt.value();
if (!StringUtils.hasText(uri)) {
uri = getApiUri(clz, method);
uri = RequestUriUtils.getApiUri(clz, method, contextPath);
}
logger.debug("Encrypt URI: {}", uri);
responseEncryptUriList.add(uri);
Expand All @@ -117,7 +118,7 @@ private void initData(Map<String, Object> beanMap) {
if (decrypt != null) {
String uri = decrypt.value();
if (!StringUtils.hasText(uri)) {
uri = getApiUri(clz, method);
uri = RequestUriUtils.getApiUri(clz, method, contextPath);
}

String decyptParam = decrypt.decyptParam();
Expand All @@ -133,7 +134,7 @@ private void initData(Map<String, Object> beanMap) {
// 注解中的URI优先级高
String uri = encryptIgnore.value();
if (!StringUtils.hasText(uri)) {
uri = getApiUri(clz, method);
uri = RequestUriUtils.getApiUri(clz, method, contextPath);
}
logger.debug("EncryptIgnore URI: {}", uri);
responseEncryptUriIgnoreList.add(uri);
Expand All @@ -142,7 +143,7 @@ private void initData(Map<String, Object> beanMap) {
if (decryptIgnore != null) {
String uri = decryptIgnore.value();
if (!StringUtils.hasText(uri)) {
uri = getApiUri(clz, method);
uri = RequestUriUtils.getApiUri(clz, method, contextPath);
}
logger.debug("DecryptIgnore URI: {}", uri);
requestDecryptUriIgnoreList.add(uri);
Expand All @@ -152,62 +153,5 @@ private void initData(Map<String, Object> beanMap) {
}
}

private String getApiUri(Class<?> clz, Method method) {
String methodType = "";
StringBuilder uri = new StringBuilder();

RequestMapping reqMapping = AnnotationUtils.findAnnotation(clz, RequestMapping.class);
if (reqMapping != null) {
uri.append(formatUri(reqMapping.value()[0]));
}

GetMapping getMapping = AnnotationUtils.findAnnotation(method, GetMapping.class);
PostMapping postMapping = AnnotationUtils.findAnnotation(method, PostMapping.class);
RequestMapping requestMapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
PutMapping putMapping = AnnotationUtils.findAnnotation(method, PutMapping.class);
DeleteMapping deleteMapping = AnnotationUtils.findAnnotation(method, DeleteMapping.class);

if (getMapping != null) {
methodType = HttpMethodTypePrefixConstant.GET;
uri.append(formatUri(getMapping.value()[0]));

} else if (postMapping != null) {
methodType = HttpMethodTypePrefixConstant.POST;
uri.append(formatUri(postMapping.value()[0]));

} else if (putMapping != null) {
methodType = HttpMethodTypePrefixConstant.PUT;
uri.append(formatUri(putMapping.value()[0]));

} else if (deleteMapping != null) {
methodType = HttpMethodTypePrefixConstant.DELETE;
uri.append(formatUri(deleteMapping.value()[0]));

} else if (requestMapping != null) {
RequestMethod requestMethod = RequestMethod.GET;
if (requestMapping.method().length > 0) {
requestMethod = requestMapping.method()[0];
}

methodType = requestMethod.name().toLowerCase() + ":";
uri.append(formatUri(requestMapping.value()[0]));

}

if (StringUtils.hasText(this.contextPath) && !"/".equals(this.contextPath)) {
if (this.contextPath.endsWith("/")) {
this.contextPath = this.contextPath.substring(0, this.contextPath.length() - 1);
}
return methodType + this.contextPath + uri.toString();
}

return methodType + uri.toString();
}

private String formatUri(String uri) {
if (uri.startsWith("/")) {
return uri;
}
return "/" + uri;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.cxytiandi.encrypt.util;


import com.cxytiandi.encrypt.springboot.HttpMethodTypePrefixConstant;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;

public class RequestUriUtils {

private static String separator = "/";

public static String getApiUri(Class<?> clz, Method method, String contextPath) {
String methodType = "";
StringBuilder uri = new StringBuilder();

RequestMapping reqMapping = AnnotationUtils.findAnnotation(clz, RequestMapping.class);
if (reqMapping != null && reqMapping.value() != null && reqMapping.value().length > 0) {
uri.append(formatUri(reqMapping.value()[0]));
}


GetMapping getMapping = AnnotationUtils.findAnnotation(method, GetMapping.class);
PostMapping postMapping = AnnotationUtils.findAnnotation(method, PostMapping.class);
RequestMapping requestMapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
PutMapping putMapping = AnnotationUtils.findAnnotation(method, PutMapping.class);
DeleteMapping deleteMapping = AnnotationUtils.findAnnotation(method, DeleteMapping.class);

if (getMapping != null && getMapping.value() != null && getMapping.value().length > 0) {
methodType = HttpMethodTypePrefixConstant.GET;
uri.append(formatUri(getMapping.value()[0]));

} else if (postMapping != null && postMapping.value() != null && postMapping.value().length > 0) {
methodType = HttpMethodTypePrefixConstant.POST;
uri.append(formatUri(postMapping.value()[0]));

} else if (putMapping != null && putMapping.value() != null && putMapping.value().length > 0) {
methodType = HttpMethodTypePrefixConstant.PUT;
uri.append(formatUri(putMapping.value()[0]));

} else if (deleteMapping != null && deleteMapping.value() != null && deleteMapping.value().length > 0) {
methodType = HttpMethodTypePrefixConstant.DELETE;
uri.append(formatUri(deleteMapping.value()[0]));

} else if (requestMapping != null && requestMapping.value() != null && requestMapping.value().length > 0) {
RequestMethod requestMethod = RequestMethod.GET;
if (requestMapping.method().length > 0) {
requestMethod = requestMapping.method()[0];
}

methodType = requestMethod.name().toLowerCase() + ":";
uri.append(formatUri(requestMapping.value()[0]));

}

if (StringUtils.hasText(contextPath) && !separator.equals(contextPath)) {
if (contextPath.endsWith(separator)) {
contextPath = contextPath.substring(0, contextPath.length() - 1);
}
return methodType + contextPath + uri.toString();
}

return methodType + uri.toString();
}

private static String formatUri(String uri) {
if (uri.startsWith(separator)) {
return uri;
}
return separator + uri;
}
}
Loading

0 comments on commit ed537ff

Please sign in to comment.