package com.ruoyi.common.filter;
|
|
import cn.hutool.json.JSONObject;
|
import com.ruoyi.common.utils.Sm4Utils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.web.util.ContentCachingResponseWrapper;
|
|
import javax.servlet.*;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.BufferedReader;
|
import java.io.IOException;
|
import java.rmi.ServerException;
|
|
public class SmCryptoFilter implements Filter {
|
|
private static final Logger logger = LoggerFactory.getLogger(SmCryptoFilter.class);
|
|
@Override
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
|
try {
|
// 对请求进行解密
|
String decryptedRequestBody = decryptRequest(httpRequest);
|
// 处理解密后的请求体 CustomRequestWrapper为自定义请求包装器,请看下面实现
|
CustomRequestWrapper customRequestWrapper = new CustomRequestWrapper(httpRequest, decryptedRequestBody);
|
|
// 继续处理请求
|
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(httpResponse);
|
chain.doFilter(customRequestWrapper, responseWrapper);
|
|
// 获取并加密响应内容
|
byte[] content = responseWrapper.getContentAsByteArray();
|
String originalResponseBody = new String(content);
|
String encryptedResponseBody = encryptResponse(originalResponseBody);
|
|
responseWrapper.setContentType("application/json");
|
JSONObject result = new JSONObject();
|
result.put("data", encryptedResponseBody);
|
result.put("code", 200);
|
|
// 设置返回编码
|
responseWrapper.setCharacterEncoding("UTF-8");
|
// 写回客户端
|
responseWrapper.reset();
|
responseWrapper.getWriter().write(result.toString());
|
responseWrapper.copyBodyToResponse();
|
|
} catch (Exception e) {
|
logger.error("内部响应错误:{}", e.getMessage());
|
e.printStackTrace();
|
// 返回标准错误响应
|
httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
httpResponse.getWriter().write("Internal Server Error");
|
}
|
}
|
|
/**
|
* 解密 HTTP 请求的主体内容。
|
*
|
* @param request HTTP 请求对象
|
* @return 解密后的请求体字符串
|
* @throws IOException 如果读取或解密过程中发生错误
|
*/
|
private String decryptRequest(HttpServletRequest request) throws IOException {
|
StringBuilder jb = new StringBuilder();
|
String line;
|
BufferedReader reader = request.getReader();
|
while ((line = reader.readLine()) != null) {
|
jb.append(line);
|
}
|
try {
|
return Sm4Utils.sm4DecryptUtil(jb.toString());
|
} catch (Exception e) {
|
throw new ServerException("参数解密失败:{}", e);
|
}
|
}
|
|
/**
|
* 加密 HTTP 响应的主体内容。
|
*
|
* @param response 原始响应体字符串
|
* @return 加密后的响应体字符串
|
*/
|
private String encryptResponse(String response) throws ServerException {
|
try {
|
return Sm4Utils.sm4EncryptUtil(response);
|
} catch (Exception e) {
|
throw new ServerException("参数解密失败:{}", e);
|
}
|
}
|
}
|