From 10b5b0e82a2125ee90ff036aed877d2e6cadfe51 Mon Sep 17 00:00:00 2001 From: wdhcr <w18700852607@163.com> Date: 星期一, 10 七月 2023 16:06:49 +0800 Subject: [PATCH] 配合前端使用jsencrypt实现接口参数加密功能, 可在application.yml中全局开启, 也可通过自定义注解@ApiDecrypt对单独接口开启. --- ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java | 34 +++ ruoyi-admin/pom.xml | 6 ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports | 1 ruoyi-common/ruoyi-common-bom/pom.xml | 7 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java | 54 ++++++ ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java | 55 ++++++ ruoyi-admin/src/main/resources/application.yml | 10 + ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java | 15 + ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java | 103 +++++++++++ ruoyi-common/pom.xml | 1 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java | 47 +++++ ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java | 52 +++++ ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java | 13 + ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java | 57 ++++++ ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java | 35 +++ ruoyi-common/ruoyi-common-cryptapi/pom.xml | 34 +++ 16 files changed, 524 insertions(+), 0 deletions(-) diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 39731b1..3d121c0 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -87,6 +87,12 @@ <artifactId>JustAuth</artifactId> </dependency> + <!-- 鎺ュ彛璇锋眰鍙傛暟鍔犲瘑妯″潡 --> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-cryptapi</artifactId> + </dependency> + <!-- skywalking 鏁村悎 logback --> <!-- <dependency>--> diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index fcc1865..878a9c3 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -173,6 +173,16 @@ publicKey: privateKey: +# api鎺ュ彛鍔犲瘑 +api-decrypt: + # 鏄惁寮�鍚叏灞�鎺ュ彛鍔犲瘑 + enable: false + # AES 鍔犲瘑澶存爣璇� + headerFlag: AES + # 鍏閽� 闈炲绉扮畻娉曠殑鍏閽� 濡傦細SM2锛孯SA + publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ== + privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= + springdoc: api-docs: # 鏄惁寮�鍚帴鍙f枃妗� diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 45493d3..e77ea23 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -33,6 +33,7 @@ <module>ruoyi-common-encrypt</module> <module>ruoyi-common-tenant</module> <module>ruoyi-common-websocket</module> + <module>ruoyi-common-cryptapi</module> </modules> <artifactId>ruoyi-common</artifactId> diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index 93d1189..5014954 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -171,6 +171,13 @@ <artifactId>ruoyi-common-websocket</artifactId> <version>${revision}</version> </dependency> + + <!-- 鎺ュ彛璇锋眰鍙傛暟鍔犲瘑妯″潡 --> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-cryptapi</artifactId> + <version>${revision}</version> + </dependency> </dependencies> </dependencyManagement> diff --git a/ruoyi-common/ruoyi-common-cryptapi/pom.xml b/ruoyi-common/ruoyi-common-cryptapi/pom.xml new file mode 100644 index 0000000..ee0c577 --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common</artifactId> + <version>${revision}</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>ruoyi-common-cryptapi</artifactId> + + <description> + ruoyi-common-cryptapi 鎺ュ彛璇锋眰鍙傛暟鍔犲瘑妯″潡 + </description> + + <dependencies> + + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-core</artifactId> + </dependency> + <dependency> + <groupId>cn.hutool</groupId> + <artifactId>hutool-crypto</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-webmvc</artifactId> + </dependency> + </dependencies> + +</project> diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java new file mode 100644 index 0000000..2e2bdee --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java @@ -0,0 +1,15 @@ +package org.dromara.cryptapi.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 褰撴爣鏈夊綋鍓嶆敞瑙g殑鎺ュ彛锛屾帴鍙g┛鍙備负鍔犲瘑瀛楃涓诧紝杩涜瑙e瘑鍚庝负dto瀵硅薄锛� 涓嶅奖鍝嶅悗缁弬鏁版牎楠屻�� + * @author wdhcr + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ApiDecrypt { +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java new file mode 100644 index 0000000..c74339b --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java @@ -0,0 +1,47 @@ +package org.dromara.cryptapi.config; + +import cn.hutool.core.collection.CollectionUtil; +import jakarta.servlet.DispatcherType; +import lombok.RequiredArgsConstructor; +import org.dromara.cryptapi.filter.CryptoFilter; +import org.dromara.cryptapi.handler.DecryptUrlHandler; +import org.dromara.cryptapi.properties.ApiDecryptProperties; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; + +import java.util.HashMap; +import java.util.List; + +@AutoConfiguration +@RequiredArgsConstructor +@EnableConfigurationProperties(ApiDecryptProperties.class) +public class ApiDecryptConfig { + + private final DecryptUrlHandler decryptUrlHandler; + + private final ApiDecryptProperties apiDecryptProperties; + + @Bean + public FilterRegistrationBean<CryptoFilter> cryptoFilterRegistration() { + FilterRegistrationBean<CryptoFilter> registration = new FilterRegistrationBean<>(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new CryptoFilter()); + List<String> urls = decryptUrlHandler.getUrls(); + if (CollectionUtil.isNotEmpty(urls) || apiDecryptProperties.getEnable()) { + registration.setEnabled(true); + registration.addUrlPatterns(urls.toArray(new String[0])); + } else { + registration.setEnabled(false); + } + registration.setName("cryptoFilter"); + HashMap<String, String> param = new HashMap<>(); + param.put(CryptoFilter.CRYPTO_PUBLIC_KEY, apiDecryptProperties.getPublicKey()); + param.put(CryptoFilter.CRYPTO_PRIVATE_KEY, apiDecryptProperties.getPrivateKey()); + param.put(CryptoFilter.CRYPTO_HEADER_FLAG, apiDecryptProperties.getHeaderFlag()); + registration.setInitParameters(param); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); + return registration; + } +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java new file mode 100644 index 0000000..29b4f4b --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java @@ -0,0 +1,57 @@ +package org.dromara.cryptapi.core; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.symmetric.AES; +import org.dromara.cryptapi.enums.EncodeType; + +import java.nio.charset.StandardCharsets; + +/** + * AES绠楁硶瀹炵幇 + * + * @author 鑰侀┈ + * @version 4.6.0 + */ +public class AesEncryptor { + + private final AES aes; + + public AesEncryptor(EncryptContext context) { + String password = context.getPassword(); + if (StrUtil.isBlank(password)) { + throw new IllegalArgumentException("AES娌℃湁鑾峰緱绉橀挜淇℃伅"); + } + // aes绠楁硶鐨勭閽ヨ姹傛槸16浣嶃��24浣嶃��32浣� + int[] array = {16, 24, 32}; + if (!ArrayUtil.contains(array, password.length())) { + throw new IllegalArgumentException("AES绉橀挜闀垮害搴旇涓�16浣嶃��24浣嶃��32浣嶏紝瀹為檯涓�" + password.length() + "浣�"); + } + aes = SecureUtil.aes(context.getPassword().getBytes(StandardCharsets.UTF_8)); + } + + + /** + * 鍔犲瘑 + * + * @param value 寰呭姞瀵嗗瓧绗︿覆 + * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡 + */ + public String encrypt(String value, EncodeType encodeType) { + if (encodeType == EncodeType.HEX) { + return aes.encryptHex(value); + } else { + return aes.encryptBase64(value); + } + } + + /** + * 瑙e瘑 + * + * @param value 寰呭姞瀵嗗瓧绗︿覆 + */ + public String decrypt(String value) { + return this.aes.decryptStr(value); + } +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java new file mode 100644 index 0000000..76804ad --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java @@ -0,0 +1,35 @@ +package org.dromara.cryptapi.core; + +import lombok.Data; +import org.dromara.cryptapi.enums.EncodeType; + +/** + * 鍔犲瘑涓婁笅鏂� 鐢ㄤ簬encryptor浼犻�掑繀瑕佺殑鍙傛暟銆� + * + * @author 鑰侀┈ + * @version 4.6.0 + */ +@Data +public class EncryptContext { + + /** + * 瀹夊叏绉橀挜 + */ + private String password; + + /** + * 鍏挜 + */ + private String publicKey; + + /** + * 绉侀挜 + */ + private String privateKey; + + /** + * 缂栫爜鏂瑰紡锛宐ase64/hex + */ + private EncodeType encode; + +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java new file mode 100644 index 0000000..9f8806d --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java @@ -0,0 +1,52 @@ +package org.dromara.cryptapi.core; + +import cn.hutool.core.codec.Base64; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.cryptapi.enums.EncodeType; + + +/** + * RSA绠楁硶瀹炵幇 + * + * @author 鑰侀┈ + * @version 4.6.0 + */ +public class RsaEncryptor { + + private final RSA rsa; + + public RsaEncryptor(EncryptContext context) { + String privateKey = context.getPrivateKey(); + String publicKey = context.getPublicKey(); + if (StringUtils.isAnyEmpty(privateKey, publicKey)) { + throw new IllegalArgumentException("RSA鍏閽ュ潎闇�瑕佹彁渚涳紝鍏挜鍔犲瘑锛岀閽ヨВ瀵嗐��"); + } + this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey)); + } + + /** + * 鍔犲瘑 + * + * @param value 寰呭姞瀵嗗瓧绗︿覆 + * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡 + */ + public String encrypt(String value, EncodeType encodeType) { + if (encodeType == EncodeType.HEX) { + return rsa.encryptHex(value, KeyType.PublicKey); + } else { + return rsa.encryptBase64(value, KeyType.PublicKey); + } + } + + /** + * 瑙e瘑 + * + * @param value 寰呭姞瀵嗗瓧绗︿覆 + */ + public String decrypt(String value) { + return this.rsa.decryptStr(value, KeyType.PrivateKey); + } +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java new file mode 100644 index 0000000..7ee356a --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java @@ -0,0 +1,13 @@ +package org.dromara.cryptapi.enums; + +public enum EncodeType { + /** + * base64缂栫爜 + */ + BASE64, + + /** + * 16杩涘埗缂栫爜 + */ + HEX +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java new file mode 100644 index 0000000..b96e74d --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java @@ -0,0 +1,54 @@ +package org.dromara.cryptapi.filter; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import lombok.SneakyThrows; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.cryptapi.core.EncryptContext; +import org.dromara.cryptapi.core.RsaEncryptor; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import java.util.Objects; + + +/** + * Crypto 杩囨护鍣� + * + * @author wdhcr + */ +public class CryptoFilter implements Filter { + + public static final String CRYPTO_PUBLIC_KEY = "publicKey"; + public static final String CRYPTO_PRIVATE_KEY = "privateKey"; + public static final String CRYPTO_HEADER_FLAG = "headerFlag"; + private RsaEncryptor rsaEncryptor; + private String headerFlag; + + + @Override + public void init(FilterConfig filterConfig) { + EncryptContext encryptContext = new EncryptContext(); + encryptContext.setPublicKey(filterConfig.getInitParameter(CryptoFilter.CRYPTO_PUBLIC_KEY)); + encryptContext.setPrivateKey(filterConfig.getInitParameter(CryptoFilter.CRYPTO_PRIVATE_KEY)); + headerFlag = filterConfig.getInitParameter(CryptoFilter.CRYPTO_HEADER_FLAG); + rsaEncryptor = new RsaEncryptor(encryptContext); + } + + @SneakyThrows + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + ServletRequest requestWrapper = null; + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE) + && (HttpMethod.PUT.matches(httpServletRequest.getMethod()) || HttpMethod.POST.matches(httpServletRequest.getMethod()))) { + requestWrapper = new DecryptRequestBodyWrapper(httpServletRequest, rsaEncryptor, headerFlag); + } + chain.doFilter(Objects.requireNonNullElse(requestWrapper, request), response); + } + + @Override + public void destroy() { + + } +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java new file mode 100644 index 0000000..8d014c8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java @@ -0,0 +1,103 @@ +package org.dromara.cryptapi.filter; + +import cn.hutool.core.codec.Base64; +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.core.exception.base.BaseException; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.cryptapi.core.AesEncryptor; +import org.dromara.cryptapi.core.EncryptContext; +import org.dromara.cryptapi.core.RsaEncryptor; +import org.dromara.cryptapi.enums.EncodeType; +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; + +/** + * 瑙e瘑璇锋眰鍙傛暟宸ュ叿绫� + * + * @author wdhcr + */ +public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper { + + private final byte[] body; + + public DecryptRequestBodyWrapper(HttpServletRequest request, RsaEncryptor rsaEncryptor, String headerFlag) throws IOException { + super(request); + String requestRsa = request.getHeader(headerFlag); + if (StringUtils.isEmpty(requestRsa)) { + throw new BaseException("鍔犲瘑AES鐨勫姩鎬佸瘑鐮佷笉鑳戒负绌�"); + } + String decryptAes = new String(Base64.decode(rsaEncryptor.decrypt(requestRsa))); + request.setCharacterEncoding(Constants.UTF8); + byte[] readBytes = IoUtil.readBytes(request.getInputStream(), false); + String requestBody = StringUtils.toEncodedString(readBytes, StandardCharsets.UTF_8); + EncryptContext encryptContext = new EncryptContext(); + encryptContext.setPassword(decryptAes); + encryptContext.setEncode(EncodeType.BASE64); + AesEncryptor aesEncryptor = new AesEncryptor(encryptContext); + String decryptBody = aesEncryptor.decrypt(requestBody); + 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-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java new file mode 100644 index 0000000..cf01ea7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java @@ -0,0 +1,55 @@ +package org.dromara.cryptapi.handler; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ReUtil; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import org.dromara.cryptapi.annotation.ApiDecrypt; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.*; +import java.util.regex.Pattern; + +/** + * 鑾峰彇闇�瑕佽В瀵嗙殑Url閰嶇疆 + * + * @author wdhcr + */ +@Data +@Component +@RequiredArgsConstructor +public class DecryptUrlHandler implements InitializingBean { + + private static final Pattern PATTERN = Pattern.compile("\\{(.*?)}"); + + private List<String> urls = new ArrayList<>(); + + private final RequestMappingHandlerMapping requestMappingHandlerMapping; + + @Override + public void afterPropertiesSet() { + Set<String> set = new HashSet<>(); + Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods(); + List<RequestMappingInfo> requestMappingInfos = map.entrySet().stream().filter(item -> { + HandlerMethod method = item.getValue(); + ApiDecrypt decrypt = method.getMethodAnnotation(ApiDecrypt.class); + // 鏍囨湁瑙e瘑娉ㄨВ鐨勫苟涓旀槸post 鎴栬�卲ut 璇锋眰鐨刪andler + return decrypt != null && CollectionUtil.containsAny(item.getKey().getMethodsCondition().getMethods(), Arrays.asList(RequestMethod.PUT, RequestMethod.POST)); + }).map(Map.Entry::getKey).toList(); + requestMappingInfos.forEach(info -> { + // 鑾峰彇娉ㄨВ涓婅竟鐨� path 鏇夸唬 path variable 涓� * + Optional.ofNullable(info.getPathPatternsCondition()) + .map(PathPatternsRequestCondition::getPatterns) + .orElseGet(HashSet::new) + .forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*"))); + }); + urls.addAll(set); + } + +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java new file mode 100644 index 0000000..f7dc6b0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java @@ -0,0 +1,34 @@ +package org.dromara.cryptapi.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * api瑙e瘑灞炴�ч厤缃被 + * @author wdhcr + */ +@Data +@ConfigurationProperties(prefix = "api-decrypt") +public class ApiDecryptProperties { + + /** + * 鍔犲瘑寮�鍏� + */ + private Boolean enable; + + /** + * 澶撮儴鏍囪瘑 + */ + private String headerFlag; + + + /** + * 鍏挜 + */ + private String publicKey; + + /** + * 绉侀挜 + */ + private String privateKey; +} diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..533d4be --- /dev/null +++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.dromara.cryptapi.config.ApiDecryptConfig -- Gitblit v1.9.3