api加解密,金额字段类型

This commit is contained in:
zt
2025-03-04 17:01:15 +08:00
parent f46223ae10
commit 485e86c6e4
40 changed files with 519 additions and 58 deletions

View File

@ -67,6 +67,17 @@
<artifactId>ruoyi-system</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
</dependencies>
</project>

View File

@ -101,7 +101,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求
.authorizeRequests()
// 对于登录login 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/app/login", "/captchaImage","/demo/tress/all").anonymous()
.antMatchers("/login", "/app/login", "/captchaImage","/demo/tress/all","/test","/testGet").anonymous()
.antMatchers("/app/login","/wgz/app/wgzRegister").permitAll()
.antMatchers(
HttpMethod.GET,

View File

@ -0,0 +1,49 @@
package com.ruoyi.framework.encrypt;
import cn.hutool.core.util.RandomUtil;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class AESUtil {
private static final Logger logger = LoggerFactory.getLogger(AESUtil.class);
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
public static String encrypt(String data, String key) {
try {
logger.info("AES加密开始加密内容{}", data);
logger.info("AES加密开始加密密钥{}", key);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(encryptedBytes);
} catch (Exception e) {
logger.error("Encryption error: ", e);
return data;
}
}
public static String decrypt(String encryptedData, String key) {
try {
logger.info("AES解密开始解密内容{}", encryptedData);
logger.info("AES解密开始解密密钥{}", key);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decryptedBytes = cipher.doFinal(Base64.decodeBase64(encryptedData));
return new String(decryptedBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
logger.error("Decryption error: ", e);
return encryptedData;
}
}
public static void main(String[] args) {
System.out.println(RandomUtil.randomString(16));
}
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.framework.encrypt;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
@ConfigurationProperties(prefix = "aes")
@Data
public class AesConfig {
private boolean enabled;
private String secretKey;
private List<String> excludePaths;
// Getters and Setters
}

View File

@ -0,0 +1,48 @@
package com.ruoyi.framework.encrypt;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class DecryptRequestWrapper extends HttpServletRequestWrapper {
private final String decryptedBody;
public DecryptRequestWrapper(HttpServletRequest request, String decryptedBody) {
super(request);
this.decryptedBody = decryptedBody;
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decryptedBody.getBytes(StandardCharsets.UTF_8));
return new ServletInputStream() {
@Override
public boolean isFinished() {
return byteArrayInputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
throw new UnsupportedOperationException();
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream(), StandardCharsets.UTF_8));
}
}

View File

@ -0,0 +1,144 @@
package com.ruoyi.framework.encrypt;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
@Component
public class EncryptDecryptFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(EncryptDecryptFilter.class);
@Autowired
private AesConfig aesConfig;
private final AntPathMatcher pathMatcher = new AntPathMatcher();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!aesConfig.isEnabled()) {
logger.info("Encryption/Decryption is disabled. Skipping.");
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (isExcludedPath(httpRequest.getRequestURI())) {
logger.info("Request URI {} is excluded. Skipping encryption/decryption.", httpRequest.getRequestURI());
chain.doFilter(request, response);
return;
}
if ("GET".equalsIgnoreCase(httpRequest.getMethod())) {
Map<String, String[]> parameterMap = new HashMap<>(httpRequest.getParameterMap());
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
String[] values = entry.getValue();
for (int i = 0; i < values.length; i++) {
logger.info("Received encoded parameter: {}", values[i]);
String decodedValue = URLDecoder.decode(values[i], StandardCharsets.UTF_8.name());
decodedValue = decodedValue.replace(" ", "+");
logger.info("Decoded parameter: {}", decodedValue);
values[i] = decryptRequestBody(decodedValue);
}
}
HttpServletRequestWrapper requestWrapper = new CustomHttpServletRequestWrapper(httpRequest, parameterMap);
EncryptResponseWrapper responseWrapper = new EncryptResponseWrapper(httpResponse);
chain.doFilter(requestWrapper, responseWrapper);
byte[] content = responseWrapper.getContent();
String responseBody = new String(content, responseWrapper.getCharacterEncoding());
String encryptedResponse = encryptResponseBody(responseBody);
httpResponse.setContentLength(encryptedResponse.getBytes().length);
httpResponse.getOutputStream().write(encryptedResponse.getBytes());
} else {
String requestBody = IOUtils.toString(httpRequest.getInputStream(), httpRequest.getCharacterEncoding());
logger.info("Received request body: {}", requestBody);
String decryptedBody = decryptRequestBody(requestBody);
logger.info("Decrypted request body: {}", decryptedBody);
DecryptRequestWrapper requestWrapper = new DecryptRequestWrapper(httpRequest, decryptedBody);
EncryptResponseWrapper responseWrapper = new EncryptResponseWrapper(httpResponse);
chain.doFilter(requestWrapper, responseWrapper);
byte[] content = responseWrapper.getContent();
String responseBody = new String(content, responseWrapper.getCharacterEncoding());
logger.info("Received response body: {}", responseBody);
String encryptedResponse = encryptResponseBody(responseBody);
logger.info("Encrypted response body: {}", encryptedResponse);
httpResponse.setContentLength(encryptedResponse.getBytes().length);
httpResponse.getOutputStream().write(encryptedResponse.getBytes());
}
}
private boolean isExcludedPath(String path) {
for (String pattern : aesConfig.getExcludePaths()) {
if (pathMatcher.match(pattern, path)) {
return true;
}
}
return false;
}
private String decryptRequestBody(String requestBody) {
try {
return AESUtil.decrypt(requestBody, aesConfig.getSecretKey());
} catch (Exception e) {
logger.error("Decryption error: ", e);
return requestBody;
}
}
private String encryptResponseBody(String responseBody) {
try {
return AESUtil.encrypt(responseBody, aesConfig.getSecretKey());
} catch (Exception e) {
logger.error("Encryption error: ", e);
return responseBody;
}
}
private static class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final Map<String, String[]> parameterMap;
public CustomHttpServletRequestWrapper(HttpServletRequest request, Map<String, String[]> parameterMap) {
super(request);
this.parameterMap = parameterMap;
}
@Override
public String getParameter(String name) {
String[] values = parameterMap.get(name);
return values != null && values.length > 0 ? values[0] : null;
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(parameterMap.keySet());
}
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
}
}

View File

@ -0,0 +1,31 @@
package com.ruoyi.framework.encrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EncryptFilterConfig {
private static final Logger logger = LoggerFactory.getLogger(EncryptFilterConfig.class);
@Autowired
private EncryptDecryptFilter encryptDecryptFilter;
public EncryptFilterConfig() {
logger.info("FilterConfig initialized");
}
@Bean
public FilterRegistrationBean<EncryptDecryptFilter> encryptDecryptFilterRegistration() {
logger.info("Registering encryptDecryptFilter");
FilterRegistrationBean<EncryptDecryptFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(encryptDecryptFilter);
registration.addUrlPatterns("/*");
registration.setName("encryptDecryptFilter");
registration.setOrder(1);
return registration;
}
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.framework.encrypt;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class EncryptResponseWrapper extends HttpServletResponseWrapper {
private final ByteArrayOutputStream outputStream;
private ServletOutputStream servletOutputStream;
private PrintWriter writer;
public EncryptResponseWrapper(HttpServletResponse response) {
super(response);
outputStream = new ByteArrayOutputStream();
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (servletOutputStream == null) {
servletOutputStream = new ServletOutputStream() {
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
throw new UnsupportedOperationException();
}
@Override
public void write(int b) throws IOException {
outputStream.write(b);
}
};
}
return servletOutputStream;
}
@Override
public PrintWriter getWriter() throws IOException {
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(outputStream, getCharacterEncoding()));
}
return writer;
}
public byte[] getContent() throws IOException {
if (writer != null) {
writer.flush();
} else if (servletOutputStream != null) {
servletOutputStream.flush();
}
return outputStream.toByteArray();
}
}