From 3e2349a4f9345279659a6f673fd5c1f35e3b5463 Mon Sep 17 00:00:00 2001
From: ColorDreams <545073804@qq.com>
Date: Fri, 26 Dec 2025 02:38:06 +0800
Subject: [PATCH] =?UTF-8?q?update=20=E4=BD=BF=E7=94=A8=E6=9B=B4=E4=BC=98?=
=?UTF-8?q?=E9=9B=85=E7=9A=84=E6=96=B9=E5=BC=8F=E4=BB=A3=E6=9B=BFFilter?=
=?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=8E=A5=E5=8F=A3=E5=8A=A0=E8=A7=A3=E5=AF=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-common/ruoyi-common-encrypt/pom.xml | 5 +
.../advice/DecryptRequestBodyAdvice.java | 97 ++++++++++++++
.../advice/EncryptResponseBodyAdvice.java | 96 ++++++++++++++
.../config/ApiDecryptAutoConfiguration.java | 18 +--
.../common/encrypt/filter/CryptoFilter.java | 110 ----------------
.../filter/DecryptRequestBodyWrapper.java | 94 -------------
.../filter/EncryptResponseBodyWrapper.java | 123 ------------------
.../properties/ApiDecryptProperties.java | 6 +-
.../encrypt/utils/MethodParameterUtils.java | 44 +++++++
9 files changed, 248 insertions(+), 345 deletions(-)
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/DecryptRequestBodyAdvice.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/EncryptResponseBodyAdvice.java
delete mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java
delete mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java
delete mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/utils/MethodParameterUtils.java
diff --git a/ruoyi-common/ruoyi-common-encrypt/pom.xml b/ruoyi-common/ruoyi-common-encrypt/pom.xml
index ed4910ef0..777ef47ff 100644
--- a/ruoyi-common/ruoyi-common-encrypt/pom.xml
+++ b/ruoyi-common/ruoyi-common-encrypt/pom.xml
@@ -22,6 +22,11 @@
ruoyi-common-core
+
+ org.dromara
+ ruoyi-common-json
+
+
org.bouncycastle
bcprov-jdk15to18
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/DecryptRequestBodyAdvice.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/DecryptRequestBodyAdvice.java
new file mode 100644
index 000000000..a104068ff
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/DecryptRequestBodyAdvice.java
@@ -0,0 +1,97 @@
+package org.dromara.common.encrypt.advice;
+
+import cn.hutool.core.io.IoUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.HttpStatus;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.encrypt.annotation.ApiEncrypt;
+import org.dromara.common.encrypt.properties.ApiDecryptProperties;
+import org.dromara.common.encrypt.utils.EncryptUtils;
+import org.dromara.common.encrypt.utils.MethodParameterUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpInputMessage;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.util.Assert;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 请求参数解密增强点
+ *
+ * @author 秋辞未寒
+ */
+@Slf4j
+@Order(Ordered.HIGHEST_PRECEDENCE) // 优先级最高,先把请求参数解密,后面的流程可能需要用到,如果不先解密,则可能无法转成正确的对象实例参数
+@ControllerAdvice
+@ConditionalOnProperty(value = ApiDecryptProperties.PREFIX_ENABLED, havingValue = "true")
+public class DecryptRequestBodyAdvice extends RequestBodyAdviceAdapter {
+
+ private final String headerFlag;
+
+ private final String privateKey;
+
+ public DecryptRequestBodyAdvice(final ApiDecryptProperties properties) {
+ this.headerFlag = properties.getHeaderFlag();
+ this.privateKey = properties.getPrivateKey();
+ }
+
+ @Override
+ public boolean supports(MethodParameter methodParameter, Type targetType, Class extends HttpMessageConverter>> converterType) {
+ return MethodParameterUtils.hasAnnotationInParameterOrMethod(methodParameter, ApiEncrypt.class);
+ }
+
+ @Override
+ public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) throws IOException {
+ ApiEncrypt ann = MethodParameterUtils.getAnnotationInParameterOrMethod(parameter, ApiEncrypt.class);
+ // 是否有注解,有就报错,没有放行
+ Assert.state(ann != null, "No ApiEncrypt annotation");
+
+ InputStream body = inputMessage.getBody();
+ HttpHeaders headers = inputMessage.getHeaders();
+
+ // 获取加密标头
+ String headerRsa = headers.getFirst(headerFlag);
+
+ // 检查是否存在加密标头
+ if (StringUtils.isBlank(headerRsa)) {
+ throw new ServiceException("没有访问权限,请联系管理员授权", HttpStatus.FORBIDDEN);
+ }
+
+ // 获取 AES 密码 采用 RSA 加密
+ String decryptAes = EncryptUtils.decryptByRsa(headerRsa, privateKey);
+ // 解密 AES 密码
+ String aesPassword = EncryptUtils.decryptByBase64(decryptAes);
+ byte[] readBytes = IoUtil.readBytes(body, false);
+ String requestBody = new String(readBytes, StandardCharsets.UTF_8);
+ // 解密 body 采用 AES 加密
+ String decryptBody = EncryptUtils.decryptByAes(requestBody, aesPassword);
+
+// log.info("API加解密 - 请求解密前的密文:{}", requestBody);
+// log.info("API加解密 - 请求解密后的内容:{}", decryptBody);
+
+ byte[] bodyBytes = decryptBody.getBytes(StandardCharsets.UTF_8);
+
+ return new HttpInputMessage() {
+ @Override
+ public InputStream getBody() throws IOException {
+ return new ByteArrayInputStream(bodyBytes);
+ }
+
+ @Override
+ public HttpHeaders getHeaders() {
+ return headers;
+ }
+ };
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/EncryptResponseBodyAdvice.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/EncryptResponseBodyAdvice.java
new file mode 100644
index 000000000..e25be4393
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/advice/EncryptResponseBodyAdvice.java
@@ -0,0 +1,96 @@
+package org.dromara.common.encrypt.advice;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.RandomUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.encrypt.annotation.ApiEncrypt;
+import org.dromara.common.encrypt.properties.ApiDecryptProperties;
+import org.dromara.common.encrypt.utils.EncryptUtils;
+import org.dromara.common.encrypt.utils.MethodParameterUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+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.lang.Nullable;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 加密响应参数增强点
+ *
+ * @author 秋辞未寒
+ */
+@Slf4j
+@Order // 优先级最低,在响应返回之前可能还会存在一些逻辑未处理完成,如果提前进行了加密,会导致未处理的逻辑无法正常执行
+@ControllerAdvice
+@ConditionalOnProperty(value = ApiDecryptProperties.PREFIX_ENABLED, havingValue = "true")
+public class EncryptResponseBodyAdvice implements ResponseBodyAdvice