@@ -438,26 +438,31 @@ private String requireConnectValue(String value, String name) {
438438 /**
439439 * 对 connect BODY 调试日志中的认证材料和设备签名脱敏。
440440 *
441+ * <p>基于深拷贝构造仅用于日志的脱敏副本,解析出的原始树保持只读;副本为调用线程私有,
442+ * 因此本方法天然线程安全,可在任意线程(如 WebSocket 读线程)并发调用。</p>
443+ *
441444 * @param json 原始 connect 请求 JSON
442445 * @return 保留协议结构但不包含认证秘密和设备签名的 JSON
443446 */
444447 String redactConnectHandshake (String json ) {
445448 try {
446449 JsonNode root = objectMapper .readTree (json );
450+ JsonNode sanitized = root .deepCopy ();
447451 JsonNode auth = root .path ("params" ).path ("auth" );
448452 if (auth .isObject ()) {
453+ com .fasterxml .jackson .databind .node .ObjectNode sanitizedAuth =
454+ (com .fasterxml .jackson .databind .node .ObjectNode ) sanitized .path ("params" ).path ("auth" );
449455 Iterator <String > names = auth .fieldNames ();
450456 while (names .hasNext ()) {
451- ((com .fasterxml .jackson .databind .node .ObjectNode ) auth )
452- .put (names .next (), "<redacted>" );
457+ sanitizedAuth .put (names .next (), "<redacted>" );
453458 }
454459 }
455460 JsonNode device = root .path ("params" ).path ("device" );
456461 if (device .isObject () && device .has ("signature" )) {
457- ((com .fasterxml .jackson .databind .node .ObjectNode ) device )
462+ ((com .fasterxml .jackson .databind .node .ObjectNode ) sanitized . path ( "params" ). path ( " device" ) )
458463 .put ("signature" , "<redacted>" );
459464 }
460- return objectMapper .writeValueAsString (root );
465+ return objectMapper .writeValueAsString (sanitized );
461466 } catch (JsonProcessingException e ) {
462467 return "<connect-payload-redacted>" ;
463468 }
0 commit comments