This is an automated email from the ASF dual-hosted git repository.

liuhongyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new b829f1606a fix: resolve duplicate header issue for JWT values with dot 
notation (#6092)
b829f1606a is described below

commit b829f1606aad66e97fafbf834f451b8350b4f79a
Author: Jast <[email protected]>
AuthorDate: Fri Aug 8 14:14:10 2025 +0800

    fix: resolve duplicate header issue for JWT values with dot notation (#6092)
---
 .../jwt/strategy/DefaultJwtConvertStrategy.java    |  3 +-
 .../strategy/DefaultJwtConvertStrategyTest.java    | 77 ++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git 
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategy.java
 
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategy.java
index 0acfb8b372..ecdf342a8e 100644
--- 
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategy.java
+++ 
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategy.java
@@ -87,8 +87,9 @@ public class DefaultJwtConvertStrategy implements 
JwtConvertStrategy {
 
             if (converter.getJwtVal().contains(".")) {
                 headers.add(converter.getHeaderVal(), parse(body, 
converter.getJwtVal().split("\\."), new AtomicInteger(0)));
+            } else {
+                headers.add(converter.getHeaderVal(), 
String.valueOf(body.get(converter.getJwtVal())));
             }
-            headers.add(converter.getHeaderVal(), 
String.valueOf(body.get(converter.getJwtVal())));
 
         }
     }
diff --git 
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategyTest.java
 
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategyTest.java
index 4a317d2bf6..e3da500be8 100644
--- 
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategyTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/strategy/DefaultJwtConvertStrategyTest.java
@@ -111,4 +111,81 @@ public class DefaultJwtConvertStrategyTest {
         
assertTrue(newExchange.getRequest().getHeaders().get("web").contains("shenyu"));
     }
 
+    /**
+     * Test to verify the fix for the duplicate header bug.
+     * After the fix, when jwtVal contains ".", only one header should be 
added with the parsed nested value.
+     */
+    @Test
+    public void testNestedJwtValueHandling() {
+        // Setup JWT body with nested structure
+        Map<String, Object> nestedJwtBody = ImmutableMap.of(
+                "user", ImmutableMap.of("name", "john", "role", "admin"),
+                "simple", "simpleValue"
+        );
+
+        // Test case 1: JWT value with dot notation (should work correctly 
after fix)
+        String handleJsonWithDot = 
"{\"converter\":[{\"jwtVal\":\"user.name\",\"headerVal\":\"username\"}]}";
+        DefaultJwtRuleHandle ruleHandleWithDot = 
defaultJwtConvertStrategy.parseHandleJson(handleJsonWithDot);
+        
+        ServerWebExchange exchangeWithDot = defaultJwtConvertStrategy
+                .convert(ruleHandleWithDot, exchange, nestedJwtBody);
+        
+        // Check the headers - after fix, should only have one header value
+        var headersWithDot = 
exchangeWithDot.getRequest().getHeaders().get("username");
+        
+        // After fix: should only have one header value with the correct 
parsed value
+        assertEquals(1, headersWithDot.size(), "After fix: Header should only 
be added once");
+        assertEquals("john", headersWithDot.get(0), "Header value should be 
parsed correctly from nested structure");
+
+        // Test case 2: JWT value without dot notation (should continue to 
work correctly)
+        String handleJsonWithoutDot = 
"{\"converter\":[{\"jwtVal\":\"simple\",\"headerVal\":\"simpleheader\"}]}";
+        DefaultJwtRuleHandle ruleHandleWithoutDot = 
defaultJwtConvertStrategy.parseHandleJson(handleJsonWithoutDot);
+        
+        ServerWebExchange exchangeWithoutDot = defaultJwtConvertStrategy
+                .convert(ruleHandleWithoutDot, exchange, nestedJwtBody);
+        
+        var headersWithoutDot = 
exchangeWithoutDot.getRequest().getHeaders().get("simpleheader");
+        
+        // This should continue to work correctly - only one header value
+        assertEquals(1, headersWithoutDot.size(), "Simple values should only 
add one header");
+        assertEquals("simpleValue", headersWithoutDot.get(0), "Header value 
should be correct");
+    }
+
+    /**
+     * Test multiple converters with mixed dot notation and simple values.
+     */
+    @Test
+    public void testMultipleConvertersWithMixedNotation() {
+        Map<String, Object> complexJwtBody = ImmutableMap.of(
+                "user", ImmutableMap.of("name", "alice", "profile", 
ImmutableMap.of("email", "[email protected]")),
+                "role", "user",
+                "permissions", ImmutableMap.of("read", true, "write", false)
+        );
+
+        String handleJson = "{\"converter\":["
+                + "{\"jwtVal\":\"user.name\",\"headerVal\":\"X-User-Name\"},"
+                + "{\"jwtVal\":\"role\",\"headerVal\":\"X-User-Role\"},"
+                + 
"{\"jwtVal\":\"user.profile.email\",\"headerVal\":\"X-User-Email\"},"
+                + 
"{\"jwtVal\":\"permissions.read\",\"headerVal\":\"X-Can-Read\"}"
+                + "]}";
+
+        DefaultJwtRuleHandle ruleHandle = 
defaultJwtConvertStrategy.parseHandleJson(handleJson);
+        ServerWebExchange newExchange = 
defaultJwtConvertStrategy.convert(ruleHandle, exchange, complexJwtBody);
+
+        // Verify all headers are added correctly
+        var headers = newExchange.getRequest().getHeaders();
+        
+        assertEquals(1, headers.get("X-User-Name").size());
+        assertEquals("alice", headers.get("X-User-Name").get(0));
+        
+        assertEquals(1, headers.get("X-User-Role").size());
+        assertEquals("user", headers.get("X-User-Role").get(0));
+        
+        assertEquals(1, headers.get("X-User-Email").size());
+        assertEquals("[email protected]", headers.get("X-User-Email").get(0));
+        
+        assertEquals(1, headers.get("X-Can-Read").size());
+        assertEquals("true", headers.get("X-Can-Read").get(0));
+    }
+
 }

Reply via email to