基于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, 面 ...
随机推荐
- uniapp 获取用户手机号
参考资料: 微信小程序官方文档 uniapp开发微信小程序获取用户手机号 页面增加一个按钮 <button open-type="getPhoneNumber" @getph ...
- k8s核心资源之Pod概念&入门使用讲解(三)
目录 1. k8s核心资源之Pod 1.1 什么是Pod? 1.2 Pod如何管理多个容器? 1.3 Pod网络 1.4 Pod存储 1.5 Pod工作方式 1.5.1 自主式Pod 1.5.2 控制 ...
- Windows下安装程序时提示未安装Microsoft Net FrameWork 2.0
问题描述 安装程序时碰到如下: 现在基本都是用win7.win10系统,缺少环境大多数都是因为系统没有启用. 解决方法 控制面板 - 程序 - 启用或关闭Windows功能 - 把第一项'NET Fr ...
- 【第十九篇】- Maven NetBeans之Spring Cloud直播商城 b2b2c电子商务技术总结
Maven NetBeans NetBeans 6.7 及更新的版本已经内置了 Maven.对于以前的版本,可在插件管理中心获取 Maven 插件.此例中我们使用的是 NetBeans 6.9. 关于 ...
- mysql中通过sql语句查询指定数据表的字段信息
mysql数据库在安装完成时,自动创建了information_schema.mysql.test这三个数据库.其中,information_schema记录了创建的所有数据库的相关信息,因此可以 ...
- Linux没有/var/log/messages日志文件
1.新安装的CentOS8没有/var/log/messages日志文件: 安装rsyslog: dnf install -y rsyslog 或 yum install -y rsys ...
- swiper轮播高度不正常
第一次进入页面可能是网速原因,图片加载问题等吧,导致轮播图高度很大,下面出现空白, 需要加入参数 autoHeight: true, observer: true, observeParents: t ...
- python学习笔记(十三)-python对Excel进行读写修改操作
日常工作中会遇到Excel的读写问题.我们可以使用xlwt 模块将数据写入Excel表格,使用xlrd 模块从Excel读取数据,使用xlutils模块和xlrd模块结合对Excel数据进行修改.下面 ...
- CF39C-Moon Craters【dp】
正题 题目链接:https://www.luogu.com.cn/problem/CF39C 题目大意 坐标轴上有\(n\)个圆,给出每个圆的位置\(c_i\)和半径\(r_i\). 要求选出最多的圆 ...
- Liunx下Mysql,MongoDB性能优化的配置
场景 这几天在赶十一上线的项目,但是突然发现接口性能不好,高并发支持不住.又不想改代码,就在数据库层面进行优化. Mysql 分区:项目中有对40万条的数据进行时间查询的要求,就算对DateTime建 ...