无关风月
2 天以前 ce0651907f18a57dae80065e01589e975530f53e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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);
        }
    }
}