OCT
REM: 1. 增加接口协议响应加密功能 2. 增加接口响应协议加密方式相关配置 3. controller 层支持协议传输加解密功能 4. 优化通信协议接口定义
This commit is contained in:
parent
f7cd5d0d3a
commit
955778b3b9
|
@ -186,13 +186,22 @@ public enum ErrorCode {
|
|||
*/
|
||||
ERR_ENCRYPT_3DES(105, "3DES加密失败"),
|
||||
/**
|
||||
* Err decrypt unknown error code.
|
||||
* The Err decrypt unknown.
|
||||
*/
|
||||
ERR_DECRYPT_UNKNOWN(106, "不支持的解密算法"),
|
||||
/**
|
||||
* Err encrypt unknown error code.
|
||||
* The Err encrypt unknown.
|
||||
*/
|
||||
ERR_ENCRYPT_UNKNOWN(107, "不支持的加密算法"),
|
||||
|
||||
/**
|
||||
* Err json encode error code.
|
||||
*/
|
||||
ERR_JSON_ENCODE(108, "Json 序列号错误"),
|
||||
/**
|
||||
* Err json decode error code.
|
||||
*/
|
||||
ERR_JSON_DECODE(109, "Json 反序列化错误"),
|
||||
;
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.dispose.pojo.dto.protocol.base.ValidGroups;
|
|||
import com.dispose.pojo.po.MulReturnType;
|
||||
import com.dispose.service.UserAccountService;
|
||||
import com.security.annotation.Decryption;
|
||||
import com.security.annotation.Encryption;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -38,6 +39,8 @@ import java.security.NoSuchAlgorithmException;
|
|||
@Api(value = "处置平台认证接口", tags = "处置平台认证接口")
|
||||
@Component
|
||||
@Validated
|
||||
@Encryption
|
||||
@Decryption
|
||||
public class AuthController {
|
||||
/**
|
||||
* The User account service.
|
||||
|
@ -55,7 +58,7 @@ public class AuthController {
|
|||
@PostMapping("/login")
|
||||
@ResponseBody
|
||||
@ApiOperation("登录")
|
||||
public ProtocolRespDTO<? extends BaseRespStatus> userLogin(@Decryption
|
||||
public ProtocolRespDTO<? extends BaseRespStatus> userLogin(
|
||||
@Validated(ValidGroups.LoginReqValid.class)
|
||||
@RequestBody ProtocolReqDTO<LoginReq> mr)
|
||||
throws NoSuchAlgorithmException {
|
||||
|
@ -95,6 +98,7 @@ public class AuthController {
|
|||
@PostMapping("/logout")
|
||||
@ResponseBody
|
||||
@ApiOperation("注销")
|
||||
@Encryption
|
||||
public ProtocolRespDTO<? extends BaseRespStatus> userLogout(@Validated(ValidGroups.LogoutReqValid.class)
|
||||
@RequestBody ProtocolReqDTO<LoginReq> mr,
|
||||
@RequestHeader HttpHeaders headers) { // 注销用户登录
|
||||
|
|
|
@ -27,6 +27,8 @@ import com.dispose.pojo.entity.DisposeDevice;
|
|||
import com.dispose.pojo.po.MulReturnType;
|
||||
import com.dispose.service.DisposeDeviceManagerService;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.security.annotation.Decryption;
|
||||
import com.security.annotation.Encryption;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -55,6 +57,8 @@ import java.util.List;
|
|||
@Api(value = "处置平台设备管理接口", tags = "处置平台设备管理接口")
|
||||
@Component
|
||||
@Validated
|
||||
@Encryption
|
||||
@Decryption
|
||||
public class DisposeDeviceManagerController {
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.lang.reflect.Type;
|
|||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class ProtocolSecurity implements RequestBodyAdvice {
|
||||
public class RequestProtocolSecurity implements RequestBodyAdvice {
|
||||
/**
|
||||
* Supports boolean.
|
||||
*
|
||||
|
@ -32,7 +32,8 @@ public class ProtocolSecurity implements RequestBodyAdvice {
|
|||
public boolean supports(@NotNull MethodParameter methodParameter,
|
||||
@NotNull Type type,
|
||||
@NotNull Class<? extends HttpMessageConverter<?>> aClass) {
|
||||
return methodParameter.hasParameterAnnotation(Decryption.class);
|
||||
return methodParameter.getContainingClass().isAnnotationPresent(Decryption.class)
|
||||
|| methodParameter.hasMethodAnnotation(Decryption.class);
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,65 @@
|
|||
package com.dispose.interceptor;
|
||||
|
||||
import com.dispose.common.ProtoCryptoType;
|
||||
import com.dispose.common.SecurityConfigValue;
|
||||
import com.security.annotation.Encryption;
|
||||
import com.security.protocol.EncryptResponseProtocol;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||
|
||||
/**
|
||||
* The type Response protocol security.
|
||||
*
|
||||
* @author <huangxin@cmhi.chinamoblie.com>
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class ResponseProtocolSecurity implements ResponseBodyAdvice<Object> {
|
||||
/**
|
||||
* Supports boolean.
|
||||
*
|
||||
* @param methodParameter the method parameter
|
||||
* @param aClass the a class
|
||||
* @return the boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(@NotNull MethodParameter methodParameter,
|
||||
@NotNull Class<? extends HttpMessageConverter<?>> aClass) {
|
||||
return methodParameter.getContainingClass().isAnnotationPresent(Encryption.class)
|
||||
|| methodParameter.hasMethodAnnotation(Encryption.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before body write protocol resp dto.
|
||||
*
|
||||
* @param o the o
|
||||
* @param methodParameter the method parameter
|
||||
* @param mediaType the media type
|
||||
* @param aClass the a class
|
||||
* @param serverHttpRequest the server http request
|
||||
* @param serverHttpResponse the server http response
|
||||
* @return the protocol resp dto
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
public Object beforeBodyWrite(Object o,
|
||||
@NotNull MethodParameter methodParameter,
|
||||
@NotNull MediaType mediaType,
|
||||
@NotNull Class<? extends HttpMessageConverter<?>> aClass,
|
||||
@NotNull ServerHttpRequest serverHttpRequest,
|
||||
@NotNull ServerHttpResponse serverHttpResponse) {
|
||||
|
||||
if (SecurityConfigValue.SECURITY_PROTOCOL_TYPE == ProtoCryptoType.CRYPTO_NONE.getCode()) {
|
||||
return o;
|
||||
} else {
|
||||
return new EncryptResponseProtocol(o, SecurityConfigValue.SECURITY_PROTOCOL_TYPE).toEncryptObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ package com.dispose.pojo.dto.protocol.base;
|
|||
|
||||
import com.dispose.common.ConstValue;
|
||||
import com.dispose.common.ErrorCode;
|
||||
import com.dispose.common.ProtoCryptoType;
|
||||
import com.dispose.common.SecurityConfigValue;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
@ -10,6 +10,7 @@ import lombok.AllArgsConstructor;
|
|||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* The type Protocol resp dto.
|
||||
|
@ -17,6 +18,7 @@ import lombok.NoArgsConstructor;
|
|||
* @param <T> the type parameter
|
||||
* @author <huangxin@cmhi.chinamoblie.com>
|
||||
*/
|
||||
@Slf4j
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
|
@ -29,7 +31,7 @@ public class ProtocolRespDTO<T> extends BaseProtocolDTO<T> {
|
|||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 状态码,用于记录服务器返回状态信息,例如HTTP返回值等.
|
||||
* The Code.
|
||||
*/
|
||||
@ApiModelProperty(value = "服务器返回状态码", example = "200")
|
||||
private Integer code;
|
||||
|
@ -37,13 +39,21 @@ public class ProtocolRespDTO<T> extends BaseProtocolDTO<T> {
|
|||
/**
|
||||
* Result protocol resp dto.
|
||||
*
|
||||
* @param <T> the type parameter
|
||||
* @param err the err
|
||||
* @param obj the obj
|
||||
* @param <T> the type parameter
|
||||
* @param err the err
|
||||
* @param httpCode the http code
|
||||
* @param respMsg the resp msg
|
||||
* @return the protocol resp dto
|
||||
*/
|
||||
public static <T> ProtocolRespDTO<T> result(ErrorCode err, T obj) {
|
||||
return result(err, obj, ProtoCryptoType.CRYPTO_NONE.getCode());
|
||||
private static <T> ProtocolRespDTO<T> result(ErrorCode err, Integer httpCode, T respMsg) {
|
||||
ProtocolRespDTO<T> resp = new ProtocolRespDTO<>();
|
||||
|
||||
resp.setVer(ConstValue.Protocol.VERSION);
|
||||
resp.setCode(httpCode);
|
||||
resp.setCryptoType(SecurityConfigValue.SECURITY_PROTOCOL_TYPE);
|
||||
resp.setTimeStamp(System.currentTimeMillis());
|
||||
resp.setMsgContent(respMsg);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,19 +62,10 @@ public class ProtocolRespDTO<T> extends BaseProtocolDTO<T> {
|
|||
* @param <T> the type parameter
|
||||
* @param err the err
|
||||
* @param respMsg the resp msg
|
||||
* @param crypto the crypto
|
||||
* @return the protocol resp dto
|
||||
*/
|
||||
public static <T> ProtocolRespDTO<T> result(ErrorCode err, T respMsg, Integer crypto) {
|
||||
ProtocolRespDTO<T> resp = new ProtocolRespDTO<>();
|
||||
|
||||
resp.setVer(ConstValue.Protocol.VERSION);
|
||||
resp.setCode(err.getHttpCode());
|
||||
resp.setCryptoType(crypto);
|
||||
resp.setTimeStamp(System.currentTimeMillis());
|
||||
resp.setMsgContent(respMsg);
|
||||
|
||||
return resp;
|
||||
public static <T> ProtocolRespDTO<T> result(ErrorCode err, T respMsg) {
|
||||
return result(err, err.getHttpCode(), respMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,19 +75,8 @@ public class ProtocolRespDTO<T> extends BaseProtocolDTO<T> {
|
|||
* @return the protocol resp dto
|
||||
*/
|
||||
public static ProtocolRespDTO<BaseRespStatus> result(ErrorCode err) {
|
||||
|
||||
ProtocolRespDTO<BaseRespStatus> resp = new ProtocolRespDTO<>();
|
||||
BaseRespStatus rspMsg = new BaseRespStatus();
|
||||
rspMsg.setStatus(err.getCode());
|
||||
rspMsg.setMessage(new String[] {err.getMsg()});
|
||||
|
||||
resp.setVer(ConstValue.Protocol.VERSION);
|
||||
resp.setCode(err.getHttpCode());
|
||||
resp.setCryptoType(ProtoCryptoType.CRYPTO_NONE.getCode());
|
||||
resp.setTimeStamp(System.currentTimeMillis());
|
||||
resp.setMsgContent(rspMsg);
|
||||
|
||||
return resp;
|
||||
BaseRespStatus rspMsg = new BaseRespStatus(err.getCode(), new String[]{err.getMsg()});
|
||||
return result(err, err.getHttpCode(), rspMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,17 +88,7 @@ public class ProtocolRespDTO<T> extends BaseProtocolDTO<T> {
|
|||
* @return the protocol resp dto
|
||||
*/
|
||||
public static ProtocolRespDTO<BaseRespStatus> result(ErrorCode errCode, Integer httpCode, String[] message) {
|
||||
ProtocolRespDTO<BaseRespStatus> resp = new ProtocolRespDTO<>();
|
||||
BaseRespStatus rspMsg = new BaseRespStatus();
|
||||
rspMsg.setStatus(errCode.getCode());
|
||||
rspMsg.setMessage(message);
|
||||
|
||||
resp.setVer(ConstValue.Protocol.VERSION);
|
||||
resp.setCode(httpCode);
|
||||
resp.setCryptoType(ProtoCryptoType.CRYPTO_NONE.getCode());
|
||||
resp.setTimeStamp(System.currentTimeMillis());
|
||||
resp.setMsgContent(rspMsg);
|
||||
|
||||
return resp;
|
||||
BaseRespStatus rspMsg = new BaseRespStatus(errCode.getCode(), message);
|
||||
return result(errCode, httpCode, rspMsg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
|||
*
|
||||
* @author <huangxin@cmhi.chinamoblie.com>
|
||||
*/
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Decryption {
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
|||
*
|
||||
* @author <huangxin@cmhi.chinamoblie.com>
|
||||
*/
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Encryption {
|
||||
}
|
||||
|
|
|
@ -73,8 +73,8 @@ public class CryptoHelper {
|
|||
/**
|
||||
* Aes 256 encryption byte [ ].
|
||||
*
|
||||
* @param plaintext the ciphertext
|
||||
* @param aesKey the aes key
|
||||
* @param plaintext the plaintext
|
||||
* @param aesKey the aes key
|
||||
* @return the byte [ ]
|
||||
* @throws NoSuchAlgorithmException the no such algorithm exception
|
||||
* @throws NoSuchPaddingException the no such padding exception
|
||||
|
@ -145,4 +145,29 @@ public class CryptoHelper {
|
|||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
|
||||
return cipher.doFinal(ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Des encryption byte [ ].
|
||||
*
|
||||
* @param plaintext the plaintext
|
||||
* @param desKey the des key
|
||||
* @return the byte [ ]
|
||||
* @throws InvalidKeyException the invalid key exception
|
||||
* @throws NoSuchAlgorithmException the no such algorithm exception
|
||||
* @throws InvalidKeySpecException the invalid key spec exception
|
||||
* @throws NoSuchPaddingException the no such padding exception
|
||||
* @throws BadPaddingException the bad padding exception
|
||||
* @throws IllegalBlockSizeException the illegal block size exception
|
||||
*/
|
||||
public static byte[] desEncryption(byte[] plaintext, String desKey) throws InvalidKeyException,
|
||||
NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException,
|
||||
IllegalBlockSizeException {
|
||||
SecureRandom sr = new SecureRandom();
|
||||
DESKeySpec desKeySpec = new DESKeySpec(desKey.getBytes());
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
|
||||
Cipher cipher = Cipher.getInstance(DES_ALGORITHM_STR);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);
|
||||
return cipher.doFinal(plaintext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package com.security.protocol;
|
||||
|
||||
import com.dispose.common.ConstValue;
|
||||
import com.dispose.common.ErrorCode;
|
||||
import com.dispose.common.ProtoCryptoType;
|
||||
import com.dispose.common.SecurityConfigValue;
|
||||
import com.dispose.pojo.dto.protocol.base.ProtocolRespDTO;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.security.arithmetic.CryptoHelper;
|
||||
import com.security.exception.SecurityProtocolException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* The type Encrypt response protocol.
|
||||
*
|
||||
* @author <huangxin@cmhi.chinamoblie.com>
|
||||
*/
|
||||
@Slf4j
|
||||
public class EncryptResponseProtocol {
|
||||
|
||||
/**
|
||||
* The Object mapper.
|
||||
*/
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* The Object.
|
||||
*/
|
||||
private final Object object;
|
||||
|
||||
/**
|
||||
* The Encrypt type.
|
||||
*/
|
||||
private final Integer encryptType;
|
||||
|
||||
/**
|
||||
* Instantiates a new Encrypt response protocol.
|
||||
*
|
||||
* @param object the object
|
||||
* @param encType the enc type
|
||||
*/
|
||||
public EncryptResponseProtocol(Object object, Integer encType) {
|
||||
this.encryptType = encType;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
/**
|
||||
* To encrypt object protocol resp dto.
|
||||
*
|
||||
* @return the protocol resp dto
|
||||
*/
|
||||
public ProtocolRespDTO<String> toEncryptObject() {
|
||||
ProtocolRespDTO<String> cryptoObject = new ProtocolRespDTO<>();
|
||||
cryptoObject.setVer(ConstValue.Protocol.VERSION);
|
||||
cryptoObject.setCryptoType(SecurityConfigValue.SECURITY_PROTOCOL_TYPE);
|
||||
cryptoObject.setTimeStamp(System.currentTimeMillis());
|
||||
|
||||
String msgContentJsonString;
|
||||
|
||||
try {
|
||||
Method getMsgMethod = object.getClass().getMethod("getMsgContent");
|
||||
Method getCode = object.getClass().getMethod("getCode");
|
||||
msgContentJsonString = new ObjectMapper().writeValueAsString(getMsgMethod.invoke(object));
|
||||
cryptoObject.setCode((Integer) getCode.invoke(object));
|
||||
} catch (Exception e) {
|
||||
log.error("Json encode message error: {}", object);
|
||||
throw new SecurityProtocolException(ErrorCode.ERR_SYSTEMEXCEPTION);
|
||||
}
|
||||
if (encryptType == ProtoCryptoType.CRYPTO_BASE64.getCode()) {
|
||||
cryptoObject.setMsgContent(CryptoHelper.base64Encryption(msgContentJsonString.getBytes(StandardCharsets.UTF_8)));
|
||||
} else if (encryptType == ProtoCryptoType.CRYPTO_AES256.getCode()) {
|
||||
try {
|
||||
byte[] encode = CryptoHelper.aes256Encryption(msgContentJsonString.getBytes(StandardCharsets.UTF_8),
|
||||
SecurityConfigValue.AES_KEY);
|
||||
cryptoObject.setMsgContent(CryptoHelper.base64Encryption(encode));
|
||||
} catch (Exception e) {
|
||||
log.error("AES256 encode message error: {}", msgContentJsonString);
|
||||
throw new SecurityProtocolException(ErrorCode.ERR_DECRYPT_AES256);
|
||||
}
|
||||
} else if (encryptType == ProtoCryptoType.CRYPTO_DES.getCode()) {
|
||||
try {
|
||||
byte[] encode = CryptoHelper.desEncryption(msgContentJsonString.getBytes(StandardCharsets.UTF_8),
|
||||
SecurityConfigValue.DES_KEY);
|
||||
cryptoObject.setMsgContent(CryptoHelper.base64Encryption(encode));
|
||||
} catch (Exception e) {
|
||||
log.error("DES256 encode message error: {}", msgContentJsonString);
|
||||
throw new SecurityProtocolException(ErrorCode.ERR_DECRYPT_3DES);
|
||||
}
|
||||
} else {
|
||||
log.error("Unknown protocol security type: {}, {}", encryptType, msgContentJsonString);
|
||||
throw new SecurityProtocolException(ErrorCode.ERR_ENCRYPT_UNKNOWN);
|
||||
}
|
||||
|
||||
return cryptoObject;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue