springboot 实现获取加密数据和解密数据

springboot 实现获取加密数据和解密数据,第1张

1 自定义注解 该注解放在作用再controller上

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface EncryptFilter {

    /**
     * 对入参是否解密
     * @return
     */
    boolean decryptRequest() default true;


    /**
     * 对出参是否加密
     */
    boolean encryptResponse() default true;


}

2 对请求数据进行数据处理


/**
 * 

接口入参解密

* RequestBodyAdvice可以理解为在@RequestBody之前需要进行的 *** 作,
* ResponseBodyAdvice可以理解为在@ResponseBody之后进行的 *** 作;
* 所以当接口需要加解密时,在使用@RequestBody接收前台参数之前可以先在RequestBodyAdvice的实现类中进行参数的解密,
* 当 *** 作结束需要返回数据时,可以在@ResponseBody之后进入ResponseBodyAdvice的实现类中进行参数的加密。
*/ @RestControllerAdvice @Slf4j public class DecryptRequestBodyAdapter extends RequestBodyAdviceAdapter { /** * 该方法用于判断当前请求,是否要执行beforeBodyRead方法 * * @param methodParameter handler方法的参数对象 * @param targetType handler方法的参数类型 * @param converterType 将会使用到的Http消息转换器类类型 * @return 返回true则会执行beforeBodyRead */ @Override public boolean supports(MethodParameter methodParameter, Type targetType, Class> converterType) { Method method = methodParameter.getMethod(); if (Objects.nonNull(method)) { EncryptFilter encryptFilter = method.getAnnotation(EncryptFilter.class); if (Objects.nonNull(encryptFilter)) { return encryptFilter.decryptRequest(); } } return false; } /** * 在Http消息转换器执转换,之前执行 * * @param inputMessage 客户端的请求数据 * @param methodParameter handler方法的参数对象 * @param targetType handler方法的参数类型 * @param converterType 将会使用到的Http消息转换器类类型 * @return 返回 一个自定义的HttpInputMessage */ @Override public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type targetType, Class> converterType) throws IOException { // 读取加密的请求体 InputStream body = inputMessage.getBody(); HttpHeaders headers = inputMessage.getHeaders(); headers.remove("Content-Length"); String s = StreamUtil.getBodyString(body); log.info("解密前请求body:" + s); if (Strings.isNotEmpty(s)) { // 使用sm4解密 String bodyDec = null; try { bodyDec = Sm4Util.decryptEcb(Constants.KEY,s); } catch (Exception e) { e.printStackTrace(); } log.info("解密后请求body:" + bodyDec); if (Strings.isNotEmpty(bodyDec)) { // 使用解密后的数据,构造新的读取流 InputStream inputStream = new ByteArrayInputStream(bodyDec.getBytes(StandardCharsets.UTF_8)); return new HttpInputMessage() { @Override public HttpHeaders getHeaders() { return inputMessage.getHeaders(); } @Override public InputStream getBody() { return inputStream; } }; } } return inputMessage; }

3 对返回结果进行数据加密 继承ResponseBodyAdvice


/**
 * 

接口出参加密

* RequestBodyAdvice可以理解为在@RequestBody之前需要进行的 *** 作,
* ResponseBodyAdvice可以理解为在@ResponseBody之后进行的 *** 作;
* 所以当接口需要加解密时,在使用@RequestBody接收前台参数之前可以先在RequestBodyAdvice的实现类中进行参数的解密,
* 当 *** 作结束需要返回数据时,可以在@ResponseBody之后进入ResponseBodyAdvice的实现类中进行参数的加密。
*/ //@RestControllerAdvice("com.example.springbootEncrypt.controller") // 表示com.example.springbootEncrypt.controller此包下的所有响应对象都会经过此拦截器,并对响应体加密 @RestControllerAdvice @Slf4j public class EncryptResponseBodyAdapter implements ResponseBodyAdvice { /** * 该方法用于判断当前请求的返回值,是否要执行beforeBodyWrite方法 * * @param methodParameter handler方法的参数对象 * @param converterType 将会使用到的Http消息转换器类类型 * @return 返回true则会执行beforeBodyWrite */ @Override public boolean supports(MethodParameter methodParameter, Class> converterType) { Method method = methodParameter.getMethod(); if (Objects.nonNull(method)) { EncryptFilter encryptFilter = method.getAnnotation(EncryptFilter.class); if (Objects.nonNull(encryptFilter)) { return encryptFilter.encryptResponse(); } } return false; } /** * 在Http消息转换器执转换,之前执行 * * @param body 服务端的响应数据 * @param methodParameter handler方法的参数对象 * @param mediaType 响应的ContentType * @param converterType 将会使用到的Http消息转换器类类型 * @param serverHttpRequest serverHttpRequest * @param serverHttpResponse serverHttpResponse * @return 返回 一个自定义的HttpInputMessage,可以为null,表示没有任何响应 */ @Override @Nullable public Object beforeBodyWrite(@Nullable Object body, MethodParameter methodParameter, MediaType mediaType, Class> converterType, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { log.info("处理请求地址:{} 的返回值", serverHttpRequest.getURI()); //获取请求数据 String srcData = JSON.toJSONString(body); log.info("加密前响应body={}", srcData); if (Objects.nonNull(body)) { //加密 String returnStr = null; try { returnStr = Sm4Util.encryptEcb(Constants.KEY,srcData); } catch (Exception e) { e.printStackTrace(); } log.info("加密后响应body:" + returnStr); //添加 encrypt 告诉前端数据已加密 //serverHttpResponse.getHeaders().add("encrypt", "e=a"); return returnStr; } return body; }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/726243.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)