-
Notifications
You must be signed in to change notification settings - Fork 7k
【新增】web 模块新增 encrypt 实现 API 加解密 #681
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master-jdk17
Are you sure you want to change the base?
Conversation
这个功能很好, |
好功能,希望能把前端也同步推送一下 @craftsman4j |
前端由作者来贡献,他估计没时间 |
兄弟,你不就是这个PR的作者吗? |
我说的项目作者 yudao |
bugbot run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Incorrect `ServletInputStream` Method Implementations
The ServletInputStream
implementation in ApiDecryptRequestBodyWrapper
incorrectly implements isFinished()
, isReady()
, and available()
methods.
isFinished()
always returnsfalse
instead oftrue
when all data has been read from the underlying stream.isReady()
always returnsfalse
instead oftrue
, despite data being immediately available from the wrappedByteArrayInputStream
.available()
returns the total body length (body.length
) instead of the remaining bytes available in the stream.
This violates the Servlet API contract and can cause issues with servlet containers, particularly in asynchronous or non-blocking I/O operations.
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiDecryptRequestBodyWrapper.java#L73-L90
Lines 73 to 90 in a784685
@Override | |
public boolean isFinished() { | |
return false; | |
} | |
@Override | |
public boolean isReady() { | |
return false; | |
} | |
@Override | |
public void setReadListener(ReadListener readListener) { | |
} | |
@Override | |
public int available() { | |
return body.length; | |
} |
Bug: Null Handler Mapping Causes NullPointerException
A NullPointerException can occur if handlerMapping.getHandler(servletRequest)
returns null. This results in mappingHandler
being null, and a subsequent call to mappingHandler.getHandler()
will throw an NPE. The existing try-catch
block only handles exceptions thrown by handlerMapping.getHandler()
, not a null return, leaving this scenario unaddressed.
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiDecryptRequestBodyFilter.java#L83-L84
Lines 83 to 84 in a784685
} | |
Object handler = mappingHandler.getHandler(); |
Bug: AES Key Generation Relies on Default Charset
AES key generation in EncryptUtils
uses key.getBytes()
, which relies on the platform's default charset. This leads to inconsistent encryption and decryption behavior across environments, as a configurable charset (e.g., from EncryptProperties
) should be used instead.
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/util/EncryptUtils.java#L57-L58
Lines 57 to 58 in a784685
public static String encryptBase64ByAES(String content, String key) { | |
byte[] byteKey = SecureUtil.generateKey(AES, key.getBytes()).getEncoded(); |
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/util/EncryptUtils.java#L66-L67
Lines 66 to 67 in a784685
public static String decryptStrByAES(String encryptString, String key) { | |
byte[] byteKey = SecureUtil.generateKey(AES, key.getBytes()).getEncoded(); |
BugBot free trial expires on July 22, 2025
You have used $0.00 of your $50.00 spend limit so far. Manage your spend limit in the Cursor dashboard.
Was this report helpful? Give feedback by reacting with 👍 or 👎
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds encryption and decryption functionality to the web module for API requests and responses. It implements a hybrid RSA + AES encryption scheme where clients encrypt data using AES and transmit the AES key encrypted with RSA.
Key changes:
- Adds encryption utilities for RSA and AES operations
- Implements request body decryption through filters
- Provides response body encryption through response advice
- Introduces annotations for marking endpoints as requiring encryption/decryption
Reviewed Changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
org.springframework.boot.autoconfigure.AutoConfiguration.imports |
Registers the new encryption auto-configuration |
EncryptUtils.java |
Utility class providing RSA and AES encryption/decryption methods |
ApiDecryptRequestBodyWrapper.java |
HTTP request wrapper that decrypts incoming request bodies |
ApiDecryptRequestBodyFilter.java |
Filter that applies request body decryption to annotated endpoints |
ApiEncrypt.java |
Annotation to mark methods requiring response encryption |
ApiDecrypt.java |
Annotation to mark methods requiring request decryption |
ApiEncryptResponseBodyAdvice.java |
Response advice that encrypts outgoing response bodies |
YudaoApiEncryptAutoConfiguration.java |
Auto-configuration class for encryption components |
EncryptProperties.java |
Configuration properties for encryption settings |
WebFilterOrderEnum.java |
Adds filter order constant for encryption filter |
Comments suppressed due to low confidence (1)
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiDecryptRequestBodyFilter.java:60
- The variable name 'apiEncrypt' is misleading as it holds an ApiDecrypt annotation. It should be renamed to 'apiDecrypt' for clarity.
ApiDecrypt apiEncrypt = getApiDecryptAnnotation(request);
|
||
@Override | ||
public boolean isFinished() { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The isFinished() method should return true when the stream has been completely read. Currently it always returns false, which may cause issues with stream handling.
return false; | |
return inputStream.available() == 0; |
Copilot uses AI. Check for mistakes.
|
||
@Override | ||
public boolean isReady() { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The isReady() method should indicate whether data is available for reading. Currently it always returns false, which may prevent proper stream reading.
return false; | |
return inputStream.available() > 0; |
Copilot uses AI. Check for mistakes.
mappingHandler = handlerMapping.getHandler(servletRequest); | ||
} catch (Exception e) { | ||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code should check if mappingHandler is null before calling getHandler() to avoid potential NullPointerException.
} | |
} | |
if (mappingHandler == null) { | |
return null; | |
} |
Copilot uses AI. Check for mistakes.
*/ | ||
public class EncryptUtils { | ||
|
||
public static final String RSA = "RSA"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The constant RSA is defined but never used in this class. Consider removing it or using it consistently throughout the encryption operations.
Copilot uses AI. Check for mistakes.
No description provided.