1. 框架优化

2. 接口响应数据增加AES加密拦截
master
陈峰 1 year ago
parent 8fa20f37f1
commit 12e0025ef6
  1. 8
      framework-core/pom.xml
  2. 2
      framework-core/src/main/java/com/unionmed/framework/crypto/AES.java
  3. 76
      framework-core/src/main/java/com/unionmed/framework/spring/mvc/response/DecryptRequestBodyAdvice.java
  4. 30
      framework-core/src/main/java/com/unionmed/framework/spring/mvc/response/RequestResponseBodyCryptProperties.java
  5. 10
      framework-core/src/main/java/com/unionmed/framework/spring/mvc/response/ResponseBodyConfiguration.java
  6. 26
      framework-core/src/main/java/com/unionmed/framework/spring/mvc/response/interceptor/EncryptionResponseBodyInterceptor.java
  7. 2
      framework-orm/pom.xml
  8. 2
      framework-test/pom.xml
  9. 2
      pom.xml

@ -5,7 +5,7 @@
<parent>
<groupId>com.unionmed</groupId>
<artifactId>unionmed-framework</artifactId>
<version>0.0.11</version>
<version>0.0.12</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -161,6 +161,12 @@
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>

@ -28,7 +28,7 @@ public class AES {
SecretKeySpec skSpec = new SecretKeySpec(toUtf8Bytes(sk), ALGORITHM);
Cipher cipher = Cipher.getInstance(PADDING);
cipher.init(Cipher.ENCRYPT_MODE, skSpec, ivSpec);
return Base64.encodeBase64String(cipher.doFinal(value.getBytes()));
return Base64.encodeBase64String(cipher.doFinal(toUtf8Bytes(value)));
} catch (Exception ex) {
log.error("AES加密失败", ex);
return null;

@ -0,0 +1,76 @@
package com.unionmed.framework.spring.mvc.response;
import com.alibaba.fastjson.JSON;
import com.unionmed.framework.crypto.AES;
import com.unionmed.framework.http.HttpHeaders;
import com.unionmed.framework.util.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
/**
* @author ianChen
* @date 2023/6/26 14:02
*/
@Slf4j
@ControllerAdvice
public class DecryptRequestBodyAdvice implements RequestBodyAdvice {
@Autowired
private RequestResponseBodyCryptProperties requestResponseBodyCryptProperties;
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public HttpInputMessage beforeBodyRead(final HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
String body = IOUtils.toString(inputMessage.getBody(), HttpHeaders.CHARSET_UTF8);
if (ObjectUtils.notEmpty(body) && requestResponseBodyCryptProperties.isEnabled() && ObjectUtils.equalsIgnore(inputMessage.getHeaders().getFirst(HttpHeaders.X_DATA_CRYPT_E), HttpHeaders.X_DATA_CRYPT_E_VALUE_TRUE)) {
body = AES.decrypt(requestResponseBodyCryptProperties.getSk(), body.substring(0, 16), body.substring(16));
}
if (log.isDebugEnabled()) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
log.debug("URI: {}, Method: {}", servletRequestAttributes.getRequest().getRequestURI(), servletRequestAttributes.getRequest().getMethod());
log.debug("Headers: {}", JSON.toJSONString(inputMessage.getHeaders().toSingleValueMap()));
log.debug("RequestParameter: {}", servletRequestAttributes.getRequest().getParameterMap() == null ? "" : JSON.toJSONString(servletRequestAttributes.getRequest().getParameterMap()));
log.debug("RequestBody: {}", body);
}
InputStream is = IOUtils.toInputStream(body, HttpHeaders.CHARSET_UTF8);
return new HttpInputMessage() {
@Override
public InputStream getBody() throws IOException {
return is;
}
@Override
public org.springframework.http.HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
};
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
}

@ -0,0 +1,30 @@
package com.unionmed.framework.spring.mvc.response;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author ianChen
* @date 2023/6/26 14:06
*/
@ConfigurationProperties(prefix = "unionmed.web-mvc.body.crypt.aes")
public class RequestResponseBodyCryptProperties {
private boolean enabled = false;
private String sk;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getSk() {
return sk;
}
public void setSk(String sk) {
this.sk = sk;
}
}

@ -3,9 +3,9 @@ package com.unionmed.framework.spring.mvc.response;
import com.unionmed.framework.spring.mvc.response.datatemplate.DataTemplateResponseBodyInterceptor;
import com.unionmed.framework.spring.mvc.response.interceptor.EncryptionResponseBodyInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
@ -18,18 +18,18 @@ import java.util.List;
* @author ianChen
* @date 2023/6/25 15:25
*/
@EnableConfigurationProperties({RequestResponseBodyCryptProperties.class})
@Configuration
public class ResponseBodyConfiguration {
@Autowired
private Environment environment;
private RequestResponseBodyCryptProperties requestResponseBodyCryptProperties;
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
// @Bean
public ResponseBodyProcessor responseBodyProcessor() {
ResponseBodyProcessorChain chain = new ResponseBodyProcessorChain();
chain.add(new DataTemplateResponseBodyInterceptor(), new EncryptionResponseBodyInterceptor(environment));
chain.add(new DataTemplateResponseBodyInterceptor(), new EncryptionResponseBodyInterceptor(requestResponseBodyCryptProperties));
return new ResponseBodyProcessor(requestMappingHandlerAdapter.getMessageConverters(), chain);//初始化过滤器
}

@ -7,10 +7,10 @@ import com.unionmed.framework.crypto.AES;
import com.unionmed.framework.http.HttpHeaders;
import com.unionmed.framework.spring.mvc.BaseReturn;
import com.unionmed.framework.spring.mvc.BaseReturnUtils;
import com.unionmed.framework.spring.mvc.response.RequestResponseBodyCryptProperties;
import com.unionmed.framework.util.Generators;
import com.unionmed.framework.util.ObjectUtils;
import org.springframework.core.MethodParameter;
import org.springframework.core.env.Environment;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;
@ -24,33 +24,23 @@ import java.util.Map;
*/
public class EncryptionResponseBodyInterceptor implements ResponseBodyInterceptor {
private final Environment environment;
private final String RESOURCE_PREFIX = "unionmed.web.response.body.crypt.aes";
private final String SK_KEY = RESOURCE_PREFIX + ".sk";
private final String ENABLED_KEY = RESOURCE_PREFIX + ".enabled";
private final boolean enabled;
private final String sk;
private final RequestResponseBodyCryptProperties properties;
public EncryptionResponseBodyInterceptor(Environment environment) {
this.environment = environment;
if (ObjectUtils.equalsIgnore(environment.getProperty(ENABLED_KEY), "true")) {
this.sk = environment.getProperty(SK_KEY);
if (ObjectUtils.isEmpty(sk))
public EncryptionResponseBodyInterceptor(RequestResponseBodyCryptProperties properties) {
this.properties = properties;
if (properties.isEnabled()) {
if (ObjectUtils.isEmpty(properties.getSk()))
throw new NullPointerException("AES SecretKey is empty");
this.enabled = true;
} else {
this.enabled = false;
this.sk = null;
}
}
@Override
public Object handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
if (!this.enabled || returnValue == null) return null;
if (!properties.isEnabled() || returnValue == null) return returnValue;
String value = webRequest.getHeader(HttpHeaders.X_DATA_CRYPT_E);
if (ObjectUtils.equalsIgnore(value, HttpHeaders.X_DATA_CRYPT_E_VALUE_TRUE)) {
returnValue = handleReturnValue(sk, Generators.randomMix(16), returnValue);
returnValue = handleReturnValue(properties.getSk(), Generators.randomMix(16), returnValue);
}
return returnValue;

@ -5,7 +5,7 @@
<parent>
<artifactId>unionmed-framework</artifactId>
<groupId>com.unionmed</groupId>
<version>0.0.11</version>
<version>0.0.12</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent>
<groupId>com.unionmed</groupId>
<artifactId>unionmed-framework</artifactId>
<version>0.0.11</version>
<version>0.0.12</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -9,7 +9,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.unionmed</groupId>
<artifactId>unionmed-framework</artifactId>
<version>0.0.11</version>
<version>0.0.12</version>
<packaging>pom</packaging>
<name>unionmed-framework</name>

Loading…
Cancel
Save