若依前后端分离版-服务端过滤器对POST请求参数解密(针对指定接口)+添加请求头信息+响应信息拦截并将数据进行加密
2、下面对 RepeatedlyRequestWrapper进行改造(数据进行解密)或者自行创建一个新的xxxxRequestWrapper类替换掉RepeatableFilter中的RepeatedlyRequestWrapper。过滤器中的RepeatedlyRequestWrapper对POST请求参数数据允许可重复读取。去除指定接口验证的话,将会是对所有接口请求参数进行解密。1、找到项目中
一、过滤器中对指定接口进行加密
去除指定接口验证的话,将会是对所有接口请求参数进行解密。
1、找到项目中的过滤器:RepeatableFilter
过滤器中的RepeatedlyRequestWrapper对POST请求参数数据允许可重复读取
2、下面对 RepeatedlyRequestWrapper进行改造(数据进行解密)或者自行创建一个新的xxxxRequestWrapper类替换掉RepeatableFilter中的RepeatedlyRequestWrapper
可添加请求头
/**
* 构建可重复读取inputStream的request
*
* @author ruoyi
*/
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
{
private static final Logger log = LoggerFactory.getLogger(RepeatedlyRequestWrapper.class);
// 重新赋值的body数据
private String bodyJsonStr;
// 重新赋值的请求头
private Map<String, String> headerMap = new HashMap<>();
//接口请求参数加密白名单
public static List<String> encryptApi;
static {//请求参数需加密的接口
List<String> list = new ArrayList<String>();
list.add("xxxxx/xxxxx/xxxxx");
list.add("xxxxx/xxxxx/xxxxx");
encryptApi = list;
}
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
{
super(request);
request.setCharacterEncoding(Constants.UTF8);
response.setCharacterEncoding(Constants.UTF8);
//数据进行解密
String shuju = preamerJiemi(request);
this.bodyJsonStr = shuju;
}
//参数解密
public String preamerJiemi(HttpServletRequest request){
//获取请求路径(接口)
StringBuffer url = request.getRequestURL();
System.out.println(url);
String shuju = null;
if(getBoolenStatus(url.toString())){//验证接口是否需要对请求参数解密
//获取请求参数
String requestData = readBodyBytes(request);
JSONObject jsonData = JSONObject.parseObject(requestData);
String data = jsonData.getString("xxxxx");//获取加密数据
if(StringUtils.isBlank(data)){
log.error("请求参数xxxxx加密数据不存在");
throw new ServiceException("请求参数xxxxx不存在");
}
try {
//对data数据进行解密(解密工具类请自行替换,需与客户端加密方式保持一致)
shuju = AES128Util.decryptAES(data,AES128Util.keyIvJson);
//请求头中添加数据(无此需求可去除)
if(StringUtils.isBlank(getHeader("xxxxx"))){
//请求头中添加数据
addHeader("xxxxx", "xxxxx");
}
}catch (Exception e){
log.error("解密失败:{}",e.getMessage());
throw new ServiceException("解密失败,请联系客服");
}
}else{
shuju = readBodyBytes(request);
}
return shuju;
}
//验证请求接口是否加入请求参数白名单
public boolean getBoolenStatus(String requestURL){
if(encryptApi != null && encryptApi.size() > 0){
for(String list:encryptApi){
if(requestURL.contains(list)){
return true;
}
}
}
return false;
}
@Override
public ServletInputStream getInputStream() throws IOException {
if(StringUtils.isEmpty(bodyJsonStr)) {
bodyJsonStr = "";
}
// 必须指定utf-8编码,否则json请求数据中如果包含中文,会出现异常
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bodyJsonStr.getBytes("utf-8"));
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBodyJsonStr() {
return bodyJsonStr;
}
public void setBodyJsonStr(String bodyJsonStr) {
this.bodyJsonStr = bodyJsonStr;
}
/**
* add a header with given name and value
*
* @param name
* @param value
*/
public void addHeader(String name, String value) {
headerMap.put(name, value);
}
@Override
public String getHeader(String name) {
log.info("getHeader --->{}",name);
String headerValue = super.getHeader(name);
if (headerMap.containsKey(name)) {
headerValue = headerMap.get(name);
}
return headerValue;
}
/**
* get the Header names
*/
@Override
public Enumeration<String> getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
for (String name : headerMap.keySet()) {
names.add(name);
}
return Collections.enumeration(names);
}
@Override
public Enumeration<String> getHeaders(String name) {
List<String> values = Collections.list(super.getHeaders(name));
if (headerMap.containsKey(name)) {
values = Arrays.asList(headerMap.get(name));
}
return Collections.enumeration(values);
}
//获取请求体中的JSON格式参数
private String readBodyBytes(HttpServletRequest request) {
String bodyContent = null;
try {
byte[] bodyBytes = readInputBody(request.getInputStream());
bodyContent = new String(bodyBytes, Constants.UTF8);
} catch (IOException e) {
throw new RuntimeException(e);
}
return bodyContent;
}
private byte[] readInputBody(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
byteArrayOutputStream.flush();
return byteArrayOutputStream.toByteArray();
}
}
响应信息进行拦截并加密
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xdsjzs.common.filter.RepeatedlyRequestWrapper;
import com.xdsjzs.common.utils.StringUtils;
import com.xdsjzs.common.utils.sign.AES128Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletRequest;
/**
* 响应信息拦截器
*/
@RestControllerAdvice
public class ResponseResultAdvice implements ResponseBodyAdvice<Object> {
private static final Logger log = LoggerFactory.getLogger(RepeatedlyRequestWrapper.class);
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;//此信息改为false的话 将不对响应信息进行拦截
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
//return null;
// 可对响应报文做一些操作
Object jsonObject = jiami(body,request);
return jsonObject;
}
/**
* 响应信息进行加密
* @param body
* @param requestWrapper
* @return
*/
public static JSONObject jiami(Object body,ServerHttpRequest requestWrapper){
JSONObject jsonDataRe = JSONObject.parseObject(JSONObject.toJSONString(body));
jsonDataRe.put("status",0);//默认不加密
String url = requestWrapper.getURI().getPath();
//验证接口是否需要对请求参数解密
if(AES128Util.getBoolenStatus(url)) {
String jsonData = jsonDataRe.getString("data");
if(StringUtils.isNotBlank(jsonData)){
//将唯一码提取出来反转奇偶位置的字符串
JSONObject jsonObject = AES128Util.fzjo(AES128Util.uniqueCode);
//进行加密
String data = AES128Util.encryptAES(jsonData,jsonObject);
jsonDataRe.put("status",1);//加密
jsonDataRe.put("data",data);
}
}
return jsonDataRe;
}
}
到此就结束了。
以下为参考文章:
HttpServletRequest修改header值_httpservletrequest 设置header_thulium_的博客-CSDN博客
重写Request,修改Request中的Body内容 - 简书
前后端分离数据传输加解密方案(建议方案二)_前后端分离密码加密解决方案_zengliangxi的博客-CSDN博客
响应拦截参考文章:
Spring Boot响应结果返回拦截_springboot拦截返回数据_InterestAndFun的博客-CSDN博客
获取所有请求参数(Map的形式返回):
public static Map getRequestParamMap(HttpServletRequest request)
{
Map map = new HashMap();
//得到枚举类型的参数名称,参数名称若有重复的只能得到第一个
Enumeration enums = request.getParameterNames();
while (enums.hasMoreElements())
{
String paramName = (String) enums.nextElement();
String paramValue = request.getParameter(paramName);
//形成键值对应的map
map.put(paramName, paramValue);
}
return map;
}
更多推荐
所有评论(0)