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> converterType) { + return MethodParameterUtils.hasAnnotationInParameterOrMethod(methodParameter, ApiEncrypt.class); + } + + @Override + public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> 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 { + + private final String headerFlag; + + private final String publicKey; + + public EncryptResponseBodyAdvice(final ApiDecryptProperties properties) { + this.headerFlag = properties.getHeaderFlag(); + this.publicKey = properties.getPublicKey(); + } + + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + ApiEncrypt ann = MethodParameterUtils.getAnnotationInParameterOrMethod(returnType, ApiEncrypt.class); + // 是否有注解 没有注解或注解中的 response()==false 说明不需要加密 + return ann != null && ann.response(); + } + + @Nullable + @Override + public Object beforeBodyWrite(@Nullable Object body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { + if (body == null) { + return null; + } + // 生成秘钥 + String aesPassword = RandomUtil.randomString(32); + // 秘钥使用 Base64 编码 + String encryptAes = EncryptUtils.encryptByBase64(aesPassword); + // Rsa 公钥加密 Base64 编码 + String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey); + + // 设置响应头 + HttpHeaders headers = response.getHeaders(); + // vue 版本需要设置 + // getAccessControlExposeHeaders 方法的返回值可能是 Collections.emptyList() ,所以不能直接 add + ArrayList accessControlExposeHeaders = CollUtil.newArrayList(headers.getAccessControlExposeHeaders()); + accessControlExposeHeaders.add(headerFlag); + headers.setAccessControlExposeHeaders(accessControlExposeHeaders); + headers.setAccessControlAllowOrigin("*"); + headers.setAccessControlAllowMethods(List.of(HttpMethod.values())); + headers.set(headerFlag, encryptPassword); + + // 原始 body 字符串 + String originalBody; + if (body instanceof CharSequence bodyString) { + // 如果body是字符串,则不需要再进行序列化处理,直接加密后返回 + originalBody = bodyString.toString(); + } else { + // 如果body不是字符串,转为JSON字符串后再进行加密返回 + originalBody = JsonUtils.toJsonString(body); + } + + // 对内容进行加密 +// String result = EncryptUtils.encryptByAes(originalBody, aesPassword); +// log.info("API加解密 - 响应加密前的密文:{}", originalBody); +// log.info("API加解密 - 响应加密后的内容:{}", result); +// return result; + return EncryptUtils.encryptByAes(originalBody, aesPassword); + } + +} diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/ApiDecryptAutoConfiguration.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/ApiDecryptAutoConfiguration.java index 38b22f388..736b63c8f 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/ApiDecryptAutoConfiguration.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/ApiDecryptAutoConfiguration.java @@ -1,14 +1,9 @@ package org.dromara.common.encrypt.config; -import jakarta.servlet.DispatcherType; -import org.dromara.common.encrypt.filter.CryptoFilter; import org.dromara.common.encrypt.properties.ApiDecryptProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.FilterRegistration; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; /** * api 解密自动配置 @@ -17,18 +12,7 @@ import org.springframework.context.annotation.Bean; */ @AutoConfiguration @EnableConfigurationProperties(ApiDecryptProperties.class) -@ConditionalOnProperty(value = "api-decrypt.enabled", havingValue = "true") +@ConditionalOnProperty(value = ApiDecryptProperties.PREFIX_ENABLED, havingValue = "true") public class ApiDecryptAutoConfiguration { - @Bean - @FilterRegistration( - name = "cryptoFilter", - urlPatterns = "/*", - order = FilterRegistrationBean.HIGHEST_PRECEDENCE, - dispatcherTypes = DispatcherType.REQUEST - ) - public CryptoFilter cryptoFilter(ApiDecryptProperties properties) { - return new CryptoFilter(properties); - } - } diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java deleted file mode 100644 index 79d58daf1..000000000 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.dromara.common.encrypt.filter; - -import cn.hutool.core.util.ObjectUtil; -import jakarta.servlet.*; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.dromara.common.core.constant.HttpStatus; -import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.core.utils.SpringUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.encrypt.annotation.ApiEncrypt; -import org.dromara.common.encrypt.properties.ApiDecryptProperties; -import org.springframework.http.HttpMethod; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.HandlerExecutionChain; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; - -import java.io.IOException; - - -/** - * Crypto 过滤器 - * - * @author wdhcr - */ -public class CryptoFilter implements Filter { - private final ApiDecryptProperties properties; - - public CryptoFilter(ApiDecryptProperties properties) { - this.properties = properties; - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest servletRequest = (HttpServletRequest) request; - HttpServletResponse servletResponse = (HttpServletResponse) response; - // 获取加密注解 - ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest); - boolean responseFlag = apiEncrypt != null && apiEncrypt.response(); - ServletRequest requestWrapper = null; - ServletResponse responseWrapper = null; - EncryptResponseBodyWrapper responseBodyWrapper = null; - - // 是否为 put 或者 post 请求 - if (HttpMethod.PUT.matches(servletRequest.getMethod()) || HttpMethod.POST.matches(servletRequest.getMethod())) { - // 是否存在加密标头 - String headerValue = servletRequest.getHeader(properties.getHeaderFlag()); - if (StringUtils.isNotBlank(headerValue)) { - // 请求解密 - requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag()); - } else { - // 是否有注解,有就报错,没有放行 - if (ObjectUtil.isNotNull(apiEncrypt)) { - HandlerExceptionResolver exceptionResolver = SpringUtils.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); - exceptionResolver.resolveException( - servletRequest, servletResponse, null, - new ServiceException("没有访问权限,请联系管理员授权", HttpStatus.FORBIDDEN)); - return; - } - } - } - - // 判断是否响应加密 - if (responseFlag) { - responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse); - responseWrapper = responseBodyWrapper; - } - - chain.doFilter( - ObjectUtil.defaultIfNull(requestWrapper, request), - ObjectUtil.defaultIfNull(responseWrapper, response)); - - if (responseFlag) { - servletResponse.reset(); - // 对原始内容加密 - String encryptContent = responseBodyWrapper.getEncryptContent( - servletResponse, properties.getPublicKey(), properties.getHeaderFlag()); - // 对加密后的内容写出 - servletResponse.getWriter().write(encryptContent); - } - } - - /** - * 获取 ApiEncrypt 注解 - */ - private ApiEncrypt getApiEncryptAnnotation(HttpServletRequest servletRequest) { - RequestMappingHandlerMapping handlerMapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); - // 获取注解 - try { - HandlerExecutionChain mappingHandler = handlerMapping.getHandler(servletRequest); - if (ObjectUtil.isNotNull(mappingHandler)) { - Object handler = mappingHandler.getHandler(); - if (ObjectUtil.isNotNull(handler)) { - // 从handler获取注解 - if (handler instanceof HandlerMethod handlerMethod) { - return handlerMethod.getMethodAnnotation(ApiEncrypt.class); - } - } - } - } catch (Exception e) { - return null; - } - return null; - } - - @Override - public void destroy() { - } -} diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java deleted file mode 100644 index 98f4bc7c8..000000000 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.dromara.common.encrypt.filter; - -import cn.hutool.core.io.IoUtil; -import jakarta.servlet.ReadListener; -import jakarta.servlet.ServletInputStream; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletRequestWrapper; -import org.dromara.common.core.constant.Constants; -import org.dromara.common.encrypt.utils.EncryptUtils; -import org.springframework.http.MediaType; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -/** - * 解密请求参数工具类 - * - * @author wdhcr - */ -public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper { - - private final byte[] body; - - public DecryptRequestBodyWrapper(HttpServletRequest request, String privateKey, String headerFlag) throws IOException { - super(request); - // 获取 AES 密码 采用 RSA 加密 - String headerRsa = request.getHeader(headerFlag); - String decryptAes = EncryptUtils.decryptByRsa(headerRsa, privateKey); - // 解密 AES 密码 - String aesPassword = EncryptUtils.decryptByBase64(decryptAes); - request.setCharacterEncoding(Constants.UTF8); - byte[] readBytes = IoUtil.readBytes(request.getInputStream(), false); - String requestBody = new String(readBytes, StandardCharsets.UTF_8); - // 解密 body 采用 AES 加密 - String decryptBody = EncryptUtils.decryptByAes(requestBody, aesPassword); - body = decryptBody.getBytes(StandardCharsets.UTF_8); - } - - @Override - public BufferedReader getReader() { - return new BufferedReader(new InputStreamReader(getInputStream())); - } - - - @Override - public int getContentLength() { - return body.length; - } - - @Override - public long getContentLengthLong() { - return body.length; - } - - @Override - public String getContentType() { - return MediaType.APPLICATION_JSON_VALUE; - } - - - @Override - public ServletInputStream getInputStream() { - final ByteArrayInputStream bais = new ByteArrayInputStream(body); - return new ServletInputStream() { - @Override - public int read() { - return bais.read(); - } - - @Override - public int available() { - return body.length; - } - - @Override - public boolean isFinished() { - return false; - } - - @Override - public boolean isReady() { - return false; - } - - @Override - public void setReadListener(ReadListener readListener) { - - } - }; - } -} diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java deleted file mode 100644 index 78e06ff73..000000000 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.dromara.common.encrypt.filter; - -import cn.hutool.core.util.RandomUtil; -import jakarta.servlet.ServletOutputStream; -import jakarta.servlet.WriteListener; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpServletResponseWrapper; -import org.dromara.common.encrypt.utils.EncryptUtils; - -import java.io.*; -import java.nio.charset.StandardCharsets; - -/** - * 加密响应参数包装类 - * - * @author Michelle.Chung - */ -public class EncryptResponseBodyWrapper extends HttpServletResponseWrapper { - - private final ByteArrayOutputStream byteArrayOutputStream; - private final ServletOutputStream servletOutputStream; - private final PrintWriter printWriter; - - public EncryptResponseBodyWrapper(HttpServletResponse response) throws IOException { - super(response); - this.byteArrayOutputStream = new ByteArrayOutputStream(); - this.servletOutputStream = this.getOutputStream(); - this.printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream)); - } - - @Override - public PrintWriter getWriter() { - return printWriter; - } - - @Override - public void flushBuffer() throws IOException { - if (servletOutputStream != null) { - servletOutputStream.flush(); - } - if (printWriter != null) { - printWriter.flush(); - } - } - - @Override - public void reset() { - byteArrayOutputStream.reset(); - } - - public byte[] getResponseData() throws IOException { - flushBuffer(); - return byteArrayOutputStream.toByteArray(); - } - - public String getContent() throws IOException { - flushBuffer(); - return byteArrayOutputStream.toString(); - } - - /** - * 获取加密内容 - * - * @param servletResponse response - * @param publicKey RSA公钥 (用于加密 AES 秘钥) - * @param headerFlag 请求头标志 - * @return 加密内容 - * @throws IOException - */ - public String getEncryptContent(HttpServletResponse servletResponse, String publicKey, String headerFlag) throws IOException { - // 生成秘钥 - String aesPassword = RandomUtil.randomString(32); - // 秘钥使用 Base64 编码 - String encryptAes = EncryptUtils.encryptByBase64(aesPassword); - // Rsa 公钥加密 Base64 编码 - String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey); - - // 设置响应头 - // vue版本需要设置 - servletResponse.addHeader("Access-Control-Expose-Headers", headerFlag); - servletResponse.setHeader("Access-Control-Allow-Origin", "*"); - servletResponse.setHeader("Access-Control-Allow-Methods", "*"); - servletResponse.setHeader(headerFlag, encryptPassword); - servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString()); - - - // 获取原始内容 - String originalBody = this.getContent(); - // 对内容进行加密 - return EncryptUtils.encryptByAes(originalBody, aesPassword); - } - - @Override - public ServletOutputStream getOutputStream() throws IOException { - return new ServletOutputStream() { - @Override - public boolean isReady() { - return false; - } - - @Override - public void setWriteListener(WriteListener writeListener) { - - } - - @Override - public void write(int b) throws IOException { - byteArrayOutputStream.write(b); - } - - @Override - public void write(byte[] b) throws IOException { - byteArrayOutputStream.write(b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - byteArrayOutputStream.write(b, off, len); - } - }; - } - -} diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java index 6aadb3e03..db6efaba6 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java @@ -8,9 +8,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties; * @author wdhcr */ @Data -@ConfigurationProperties(prefix = "api-decrypt") +@ConfigurationProperties(prefix = ApiDecryptProperties.PREFIX) public class ApiDecryptProperties { + public static final String PREFIX = "api-decrypt"; + + public static final String PREFIX_ENABLED = PREFIX + ".enabled"; + /** * 加密开关 */ diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/utils/MethodParameterUtils.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/utils/MethodParameterUtils.java new file mode 100644 index 000000000..aa47fafe9 --- /dev/null +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/utils/MethodParameterUtils.java @@ -0,0 +1,44 @@ +package org.dromara.common.encrypt.utils; + +import lombok.NoArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.lang.Nullable; + +import java.lang.annotation.Annotation; + +/** + * 方法参数工具类 + * + * @author 秋辞未寒 + */ +@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) +public class MethodParameterUtils { + + /** + * 判断参数或方法上是否有指定注解 + * + * @param parameter 参数 + * @param annotationClass 注解类 + * @return 是否有指定注解 + */ + public static boolean hasAnnotationInParameterOrMethod(MethodParameter parameter, Class annotationClass) { + return getAnnotationInParameterOrMethod(parameter, annotationClass) != null; + } + + /** + * 获取参数或方法上的指定注解 + * + * @param parameter 参数 + * @param annotationClass 注解类 + * @return 获取参数或方法上的指定注解 + */ + @Nullable + public static T getAnnotationInParameterOrMethod(MethodParameter parameter, Class annotationClass) { + T annotation = parameter.getParameterAnnotation(annotationClass); + if (annotation == null) { + annotation = parameter.getMethodAnnotation(annotationClass); + } + return annotation; + } + +}