@@ -221,6 +221,7 @@ private boolean isValidTimestamp(String timeStamp) {
221221
222222 /**
223223 * Generate SHA-256 signature including request parameters
224+ * Modified to support long parameters and maintain compatibility with client-side signature generation
224225 *
225226 * @param request the HTTP servlet request
226227 * @param accessKey the access key
@@ -230,8 +231,8 @@ private boolean isValidTimestamp(String timeStamp) {
230231 */
231232 private static String generateSignatureWithParams (HttpServletRequest request , String accessKey , String timeStamp , String secretKey ) {
232233 try {
233- // Get all request parameters and build sorted parameter string
234- Map <String , String > allParams = getAllRequestParams (request );
234+ // Get all request parameters without length filtering to support long parameters
235+ Map <String , String > allParams = getAllRequestParamsWithoutLengthFilter (request );
235236 String sortedParamString = buildSortedParamString (allParams );
236237
237238 // Use secure string concatenation with delimiter: accessKey|timestamp|sortedParams|secretKey
@@ -287,6 +288,49 @@ private static Map<String, String> getAllRequestParams(HttpServletRequest reques
287288
288289 return params ;
289290 }
291+
292+ /**
293+ * Get all request parameters from the HTTP request without length filtering
294+ * Supports both URL query parameters and JSON request body parameters
295+ * This method is used for signature generation to support long parameters
296+ *
297+ * @param request the HTTP servlet request
298+ * @return map of all request parameters without length restrictions
299+ */
300+ private static Map <String , String > getAllRequestParamsWithoutLengthFilter (HttpServletRequest request ) {
301+ LinkedHashMap <String , String > params = new LinkedHashMap <>();
302+
303+ // Get URL query parameters without length filtering
304+ Enumeration <String > paramNames = request .getParameterNames ();
305+ while (paramNames .hasMoreElements ()) {
306+ String paramName = paramNames .nextElement ();
307+ String paramValue = request .getParameter (paramName );
308+ // Only exclude authentication-related parameters, no length validation
309+ if (paramValue != null && !ACCESS_KEY_NAME .equals (paramName )
310+ && !TIMESTAMP .equals (paramName ) && !SIGN .equals (paramName )) {
311+ params .put (paramName , paramValue );
312+ }
313+ }
314+
315+ // Extract parameters from JSON request body for POST requests without length filtering
316+ if ("POST" .equalsIgnoreCase (request .getMethod ())) {
317+ String contentType = request .getContentType ();
318+ if (contentType != null && contentType .toLowerCase ().contains ("application/json" )) {
319+ Map <String , String > jsonParams = extractJsonParamsWithoutLengthFilter (request );
320+ // Merge JSON parameters with query parameters, JSON params take precedence
321+ for (Map .Entry <String , String > entry : jsonParams .entrySet ()) {
322+ String paramName = entry .getKey ();
323+ String paramValue = entry .getValue ();
324+ if (paramValue != null && !ACCESS_KEY_NAME .equals (paramName )
325+ && !TIMESTAMP .equals (paramName ) && !SIGN .equals (paramName )) {
326+ params .put (paramName , paramValue );
327+ }
328+ }
329+ }
330+ }
331+
332+ return params ;
333+ }
290334
291335 /**
292336 * Extract parameters from JSON request body
@@ -356,6 +400,74 @@ private static Map<String, String> extractJsonParams(HttpServletRequest request)
356400 return params ;
357401 }
358402
403+ /**
404+ * Extract parameters from JSON request body without length filtering
405+ * Supports nested JSON structures through recursive flattening
406+ * This method is used for signature generation to support long parameters
407+ *
408+ * @param request the HTTP servlet request
409+ * @return map of parameters extracted from JSON body without length restrictions
410+ */
411+ private static Map <String , String > extractJsonParamsWithoutLengthFilter (HttpServletRequest request ) {
412+ Map <String , String > params = new HashMap <>();
413+
414+ try {
415+ String jsonBody = null ;
416+
417+ // Check if request is already a cached wrapper
418+ if (request instanceof CachedBodyHttpServletRequest ) {
419+ jsonBody = ((CachedBodyHttpServletRequest ) request ).getBody ();
420+ } else {
421+ // Try to read from the request directly
422+ // This may fail if the stream has already been consumed
423+ try {
424+ StringBuilder sb = new StringBuilder ();
425+ try (BufferedReader reader = request .getReader ()) {
426+ String line ;
427+ while ((line = reader .readLine ()) != null ) {
428+ sb .append (line );
429+ }
430+ }
431+ jsonBody = sb .toString ();
432+ } catch (IllegalStateException e ) {
433+ // getReader() has already been called, try to create a cached wrapper
434+ logger .warn ("Request body has already been read, attempting to create cached wrapper" );
435+ try {
436+ CachedBodyHttpServletRequest cachedRequest = new CachedBodyHttpServletRequest (request );
437+ jsonBody = cachedRequest .getBody ();
438+ } catch (Exception ex ) {
439+ logger .warn ("Failed to create cached request wrapper: {}" , ex .getMessage ());
440+ return params ; // Return empty params if we can't read the body
441+ }
442+ }
443+ }
444+
445+ if (jsonBody != null && !jsonBody .trim ().isEmpty ()) {
446+ try {
447+ JSONObject jsonObject = JSON .parseObject (jsonBody );
448+ // Use recursive flattening for better handling of nested structures
449+ Map <String , Object > flattenedParams = new HashMap <>();
450+ for (String key : jsonObject .keySet ()) {
451+ Object value = jsonObject .get (key );
452+ processObject (flattenedParams , key , value );
453+ }
454+
455+ // Convert flattened object map to string map without length filtering
456+ for (Map .Entry <String , Object > entry : flattenedParams .entrySet ()) {
457+ params .put (entry .getKey (), entry .getValue ().toString ());
458+ }
459+ } catch (Exception e ) {
460+ logger .warn ("Failed to parse JSON body: {}" , e .getMessage ());
461+ }
462+ }
463+
464+ } catch (Exception e ) {
465+ logger .warn ("Failed to extract JSON parameters: {}" , e .getMessage ());
466+ }
467+
468+ return params ;
469+ }
470+
359471 /**
360472 * Recursively process object to flatten complex objects (Map and List) into flat key-value pairs
361473 * This approach provides better handling of nested structures compared to simple normalization
0 commit comments