Commit 5277a47f by lixian7

请求加密、返回解密拦截器

parent 4787423d
......@@ -45,6 +45,11 @@
<artifactId>infra</artifactId>
<version>${parent.version}</version>
</dependency>
<dependency>
<groupId>com.hikcreate.edl.common</groupId>
<artifactId>sdk</artifactId>
<version>1.9-SNAPSHOT</version>
</dependency>
</dependencies>
<profiles>
......
package com.hikcreate.edl.pub.web.mobile.api.intercept;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hikcreate.edl.common.sdk.util.EncryptStringAes;
import com.hikcreate.edl.pub.web.mobile.infra.core.annotatiion.BodyDecryptAnnotation;
import com.hikcreate.edl.pub.web.mobile.infra.core.annotatiion.HeaderDecryptAnnotation;
import com.hikcreate.edl.pub.web.mobile.infra.model.param.request.BaseEncryptReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
/**
* 请求解密拦截器
*
* @author lixian
* @description
* @date 2020/6/18 17:32
**/
@Slf4j
@ControllerAdvice
public class DecryptRequestBodyAdvice implements RequestBodyAdvice {
ObjectMapper objectMapper = new ObjectMapper();
public static void main( String[] args ) {
String value = "{\"id\":123,\"name\":\"李\"}";
System.out.println(EncryptStringAes.encryptAes(value, "AES/ECB/PKCS5Padding"));
}
@Override
public boolean supports( MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass ) {
return true;
}
@Override
public HttpInputMessage beforeBodyRead( HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass ) throws IOException {
XHttpInputMessage xHttpInputMessage = new XHttpInputMessage(httpInputMessage, methodParameter);
return xHttpInputMessage;
/*return new HttpInputMessage() {
@Override
public InputStream getBody() throws IOException {
String bodyStr = IOUtils.toString(httpInputMessage.getBody());
log.info("Request Body encrypt:{}",bodyStr);
BaseEncryptReq encryptReq = objectMapper.readValue(bodyStr, BaseEncryptReq.class);
String decryptStr = EncryptStringAes.decryptAes(encryptReq.getEncData(), "AES/ECB/PKCS5Padding");
return IOUtils.toInputStream(decryptStr, "utf-8");
}
@Override
public HttpHeaders getHeaders() {
return httpInputMessage.getHeaders();
}
};*/
}
@Override
public Object afterBodyRead( Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass ) {
try {
log.info("Request Body 明文: " + objectMapper.writeValueAsString(o));
} catch ( Exception e ) {
e.printStackTrace();
}
return o;
}
@Override
public Object handleEmptyBody( Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass ) {
return o;
}
//这里实现了HttpInputMessage 封装一个自己的HttpInputMessage
public static class XHttpInputMessage implements HttpInputMessage {
private HttpHeaders headers;
private InputStream body;
private MethodParameter methodParameter;
public XHttpInputMessage( HttpInputMessage httpInputMessage, MethodParameter methodParameter ) throws IOException {
this.headers = httpInputMessage.getHeaders();
this.body = httpInputMessage.getBody();
this.methodParameter = methodParameter;
//解密请求数据
decrypt();
}
/**
* 解密请求数据
*/
private void decrypt() {
try {
ObjectMapper objectMapper = new ObjectMapper();
String encryptStr = null;
if ( this.methodParameter.getMethod().isAnnotationPresent(BodyDecryptAnnotation.class) ) {
String bodyStr = IOUtils.toString(this.body);
log.info("Request Body 密文:{}", bodyStr);
BaseEncryptReq encryptReq = objectMapper.readValue(bodyStr, BaseEncryptReq.class);
encryptStr = encryptReq.getEncData();
} else if ( this.methodParameter.getMethod().isAnnotationPresent(HeaderDecryptAnnotation.class) ) {
HeaderDecryptAnnotation annotation = this.methodParameter.getMethodAnnotation(HeaderDecryptAnnotation.class);
encryptStr = this.headers.getFirst(annotation.header());
log.info("Request Header 密文:{}", encryptStr);
}
if ( StrUtil.isNotBlank(encryptStr) ) {
//解密
String decryptStr = EncryptStringAes.decryptAes(encryptStr, "AES/ECB/PKCS5Padding");
this.body = IOUtils.toInputStream(decryptStr, "utf-8");
}
} catch ( Exception e ) {
log.error("Request Body 解密异常:{}", e);
}
}
@Override
public InputStream getBody() {
return body;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}
}
package com.hikcreate.edl.pub.web.mobile.api.intercept;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hikcreate.edl.common.sdk.util.EncryptStringAes;
import com.hikcreate.edl.pub.web.mobile.infra.core.Result;
import com.hikcreate.edl.pub.web.mobile.infra.core.annotatiion.ResponseEncryptAnnotation;
import com.hikcreate.edl.pub.web.mobile.infra.model.param.response.BaseEncryptRes;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* 返回加密拦截器
* 返回对象必须为com.hikcreate.edl.pub.web.mobile.infra.core.Result类型
* 加密后信息保存于Result.data
* @author lixian
* @description
* @date 2020/6/19 10:39
**/
@Slf4j
@ControllerAdvice
public class EncryptResponseBodyAdvice implements ResponseBodyAdvice {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public boolean supports( MethodParameter methodParameter, Class aClass ) {
return true;
}
@Override
public Object beforeBodyWrite( Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse ) {
try {
log.info("Response body 明文: {}",objectMapper.writeValueAsString(o));
if(methodParameter.getMethod().isAnnotationPresent(ResponseEncryptAnnotation.class) && o instanceof Result) {
//进行加密
Result<Object> result= (Result<Object>)o;
Object data = result.getData();
String dataStr = objectMapper.writeValueAsString(data);
String encryptStr = EncryptStringAes.encryptAes(dataStr, "AES/ECB/PKCS5Padding");
BaseEncryptRes baseEncryptRes = new BaseEncryptRes();
baseEncryptRes.setEncData(encryptStr);
result.setData(baseEncryptRes);
o = result;
log.info("Response body 密文: {}",objectMapper.writeValueAsString(o));
}
} catch ( Exception e ) {
log.error("Response body 加密异常:{}", e);
}
return o;
}
}
package com.hikcreate.edl.pub.web.mobile.infra.core.annotatiion;
import com.hikcreate.edl.pub.web.mobile.infra.core.enums.DecryptModeEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 请求体解密注解
* @author lixian
* @description
* @date 2020/6/19 10:02
**/
@Retention( RetentionPolicy.RUNTIME)
@Target( ElementType.METHOD)
public @interface BodyDecryptAnnotation {
/**
* 解密方式
* @return
*/
DecryptModeEnum mode() default DecryptModeEnum.AES;
}
package com.hikcreate.edl.pub.web.mobile.infra.core.annotatiion;
import com.hikcreate.edl.pub.web.mobile.infra.core.constant.HttpHeaderConstants;
import com.hikcreate.edl.pub.web.mobile.infra.core.enums.DecryptModeEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 请求header解密注解
* @author lixian
* @description
* @date 2020/6/19 10:02
**/
@Retention( RetentionPolicy.RUNTIME)
@Target( ElementType.METHOD)
public @interface HeaderDecryptAnnotation {
/**
* 解密方式
* @return
*/
DecryptModeEnum mode() default DecryptModeEnum.AES;
/**
* 保存加密信息的header字段
* @return
*/
String header() default HttpHeaderConstants.HIK_ENC_DATA;
}
package com.hikcreate.edl.pub.web.mobile.infra.core.annotatiion;
import com.hikcreate.edl.pub.web.mobile.infra.core.enums.EncryptModeEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.METHOD )
public @interface ResponseEncryptAnnotation {
/**
* 加密方式
*
* @return
*/
EncryptModeEnum mode() default EncryptModeEnum.AES;
}
package com.hikcreate.edl.pub.web.mobile.infra.core.constant;
/**
* http请求头变量名
* @author lixian
* @description
* @date 2020/6/18 17:12
**/
public class HttpHeaderConstants {
public static final String HIK_PARK_APPID = "HIK-PARK-APPID";
public static final String HIK_ENC_DATA = "HIK-ENC-DATA";
}
package com.hikcreate.edl.pub.web.mobile.infra.core.enums;
/**
* 解密方式枚举
* @author lixian
* @description
* @date 2020/6/19 10:04
**/
public enum DecryptModeEnum {
AES;
}
package com.hikcreate.edl.pub.web.mobile.infra.core.enums;
/**
* 加密方式枚举
* @Description
* @Author lixian
* @Date 2020/6/19 11:22
**/
public enum EncryptModeEnum {
AES;
}
package com.hikcreate.edl.pub.web.mobile.infra.core.util;
/**
* description:
*
* @author: xieshixiang
* @time:2020/6/18 11:28
**/
public class SecurityUtil {
}
package com.hikcreate.edl.pub.web.mobile.infra.model.param.request;
import lombok.Data;
/**
* 公共加密请求体类
* @author lixian
* @description
* @date 2020/6/19 9:28
**/
@Data
public class BaseEncryptReq {
/**
* 加密字段
*/
String encData;
}
package com.hikcreate.edl.pub.web.mobile.infra.model.param.response;
import lombok.Data;
/**
* 公共加密返回消息类
* @author lixian
* @description
* @date 2020/6/19 10:44
**/
@Data
public class BaseEncryptRes {
/**
* 加密字段
*/
String encData;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment