基于RequestBodyAdvice和ResponseBodyAdvice来实现spring中参数的加密和解密
在日常开发中,有时候我们经常需要和第三方接口打交道,有时候是我们调用别人的第三方接口,有时候是别人在调用我们的第三方接口,那么为了调用接口的安全性,一般都会对传输的数据进行加密操作,如果每个接口都由我们自己去手动加密和解密,那么工作量太大而且代码冗余。那么有没有简单的方法,借助 spring 提供的 RequestBodyAdvice 和 ResponseBodyAdvice 可以实现解密和加密操作。
需求:
1,后台方法上如果有@Encrypt注解和@RequestBody修饰的方法,需要进行参数的解密
2,后台方法上如果有@Encrypt注解和@ResponseBody修饰的方法,需要进行参数的加密
3,加密和解密规则
加密:对返回的值中增加-encrypt值
解密:对传入的值中删除-encrypt值
注:
1,@Encrypt 为自定义的一个注解。
2,此处为了简单,就使用删除或增加-encrypt这个,实际情况下可以使用复杂的加解密规则
前置知识:
RequestBodyAdvice:在 sping 4.2 新加入的一个接口,它可以使用在 @RequestBody 或 HttpEntity 修改的参数之前进行参数的处理,比如进行参数的解密。
ResponseBodyAdvice:在 spring 4.1 新加入的一个接口,在消息体被HttpMessageConverter写入之前允许Controller 中 @ResponseBody修饰的方法或ResponseEntity调整响应中的内容,比如进行相应的加密。
功能实现:
1,编写加密注解类(Encrypt)
/**
* 进行参数加密和解密
*
* @author huan.fu
* @date 2018/9/28 - 16:08
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Encrypt {
}
2,编写RequestBodyAdvice接口实现类,实现数据的解密操作
/**
* 解密数据
*
* @author huan.fu
* @date 2018/9/28 - 16:09
*/
@Slf4j
@RestControllerAdvice
public class ParamEncryptRequestBodyAdvice implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return methodParameter.hasParameterAnnotation(RequestBody.class);
}
@Override
public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
return new HttpInputMessage() {
@Override
public InputStream getBody() throws IOException {
log.info("此处进行解密数据");
return new ByteArrayInputStream(IOUtils.toString(httpInputMessage.getBody()).replace("-encrypt", "").getBytes(StandardCharsets.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) {
return o;
}
}
3,编写ResponseBodyAdvice接口实现类,实现数据的加密操作
/**
* 加密数据
*
* @author huan.fu
* @date 2018/9/28 - 16:19
*/
@Slf4j
@RestControllerAdvice
public class ParamEncryptResponseBodyAdvice implements ResponseBodyAdvice {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return returnType.hasMethodAnnotation(ResponseBody.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
log.info("此处进行加密数据");
if (null != body) {
try {
Map map = objectMapper.readValue(objectMapper.writeValueAsString(body), Map.class);
map.forEach((key, value) -> map.put(key, value + "-encrypt"));
return map;
} catch (IOException e) {
log.error("加密数据失败.", e);
}
}
return body;
}
}
4,编写控制层进行测试
/**
* 用户信息控制器
*
* @author huan.fu
* @date 2018/9/28 - 15:55
*/
@RestController
@RequestMapping("user-info")
@Slf4j
public class UserInfoController {
/**
* 添加用户实现返回值加密
*
* @param userInfo
* @return
*/
@PostMapping("add")
@Encrypt
public UserInfo add(@RequestBody UserInfo userInfo) {
log.info("添加新用户:[{}]", userInfo);
return userInfo;
}
/**
* 修改实现获取的参数进行解密
*
* @param userInfo
* @return
*/
@PostMapping("update")
public UserInfo update(@Encrypt @RequestBody UserInfo userInfo) {
log.info("修改用户信息:[{}]", userInfo);
return userInfo;
}
}
5,测试参数的解密操作
可以看到:参数中的-encrypt 传递后后台被后台自动截取了,这样就类似于解密操作。
6,测试返回值的加密操作
可以看到:返回的值后面都有一个 -encrypt ,这样就实现了类似于加密操作。
基于RequestBodyAdvice和ResponseBodyAdvice来实现spring中参数的加密和解密的更多相关文章
- Spring 中参数名称解析 - ParameterNameDiscoverer
Spring 中参数名称解析 - ParameterNameDiscoverer Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.ht ...
- 探讨.NET Core中实现AES加密和解密以及.NET Core为我们提供了什么方便!
前言 对于数据加密和解密每次我都是从网上拷贝一份,无需有太多了解,由于在.net core中对加密和解密目前全部是统一了接口,只是做具体的实现,由于遇到过问题,所以将打算基本了解下其原理,知其然足矣, ...
- JAVA中AES对称加密和解密
AES对称加密和解密 package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingExce ...
- JAVA中AES对称加密和解密以及与Python兼容
引言:本文主要解决Java中用AES加密及解密,同时可通过Python脚本对Java加密后的字符进行解密的操作. 由于近期工作中用到需要使用Java对一串密钥进行加密,并且后台通过Python语言读取 ...
- spring中 的MD5 加密
//对密码进行加密(不需要使用其他Md5工具 .spring中有 在digestUtils) String password = DigestUtils.md5DigestAsHex( ...
- OPENSSL安装 以及使用openssl中的AES加密和解密
OPENSSL安装:(VS) 1:第一步和所有的软件安装一样. 2:将OPENSSL中INLUCDE 和 LIB 分别拷贝到VS中VC的INLUCDE 和LIB目录下(我的机器上的目录是:C:\Pro ...
- asp.net中实现MD5加密、解密的方法
这个MD5加密.解密的方法会使用即可. 使用时的代码备忘:Response.Write(FormsAuthentication.HashPasswordForStoringInConfigFile(& ...
- js中实现base64加密、解密
//base64加密 解密 /* //1.加密 var result = Base.encode('125中文'); //--> "MTI15Lit5paH" //2.解密 ...
- Spring中的面向切面编程(AOP)简介
一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...
随机推荐
- openswan协商流程之(四):main_inI2_outR2()
主模式第四包:main_inI2_outR2 1. 序言 main_inI2_outR2()函数是ISAKMP协商过程中第四包的核心处理函数的入口,同时在此处理流程中已经获取到足够的隧道信息,可以生成 ...
- footer沉底效果
介绍一个简单直接的方法: flex布局 heml,body{ height: 100%; min-height: 100%; display: flex; flex-direction: column ...
- ysoserial CommonsColletions5分析
我们知道,AnnotationInvocationHandler类在JDK8u71版本以后,官方对readobject进行了改写. 所以要挖掘出一条能替代的类BadAttributeValueExpE ...
- Docker部署启动错误,需要手动进入Docker的容器里,启动程序,排查错误
#docker-compose build --no-cache //重新创建容器,不管有没有 #docker-compose up #docker-compose up -d //后台启动并运行容器 ...
- python面向对象(封装,继承,多态)
python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...
- YOLO v3 & Pascal VOC数据集
代码地址:https://github.com/YunYang1994/tensorflow-yolov3 https://hackernoon.com/understanding-yolo-f5a7 ...
- Linux档案权限篇(一)
查看档案的属性"ls-al". 即列出所有的档案的详细权限与属性(包括隐藏文件) 权限 第一个字符代表档案的类型: d:代表是目录 -:代表是文件 l:代表是连接文件(相当于win ...
- redis的持久化 与事务管理
1. redis的持久化 Redis的持久化主要分为两部分:RDB(Redis DataBase), AOF(Append Only File) 2. 什么是redis 的持久化 在指定 ...
- vue1.0,2.0区别 生命周期
1.生命周期 删除 beforeCompile compiled ready,新增beforeMounted mounted beforeUpdate updated 2.for循环里取消了$ind ...
- SpringBoot之SpringSecurity权限注解在方法上进行权限认证多种方式
前言 Spring Security支持方法级别的权限控制.在此机制上,我们可以在任意层的任意方法上加入权限注解,加入注解的方法将自动被Spring Security保护起来,仅仅允许特定的用户访问, ...