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

apupier pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new f745392821dc CAMEL-23592: camel-itest - update ShiroOverJmsTest for 
renamed Shiro security headers
f745392821dc is described below

commit f745392821dc552a330ad558b25e9e842c39a783
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu May 28 10:19:53 2026 +0200

    CAMEL-23592: camel-itest - update ShiroOverJmsTest for renamed Shiro 
security headers
    
    After CAMEL-23592 the three Shiro security headers (SHIRO_SECURITY_TOKEN,
    SHIRO_SECURITY_USERNAME, SHIRO_SECURITY_PASSWORD) carry their value in the
    Camel* namespace (CamelShiroSecurityToken etc.). The default
    JmsHeaderFilterStrategy filters every Camel* header at the transport
    boundary, which is the intended behavior for untrusted producers but
    strips the serialized authentication token from trusted Shiro-over-JMS
    routes that previously relied on the old non-Camel-prefixed value
    surviving the JMS round-trip.
    
    ShiroOverJmsTest demonstrates the Shiro-over-JMS pattern and started
    failing because the consumer-side policy could no longer read the token
    from the message: the failed message went to the dead-letter mock
    (expected 0, was 1). The test was passing on main only because its
    incremental-build scope did not exercise camel-itest after the rename;
    the regression is latent on main too.
    
    - ShiroOverJmsTest: configure a small subclass of JmsHeaderFilterStrategy
      on the JMS component that opts the three Shiro security headers back
      in (returns false from applyFilterToCamelHeaders /
      applyFilterToExternalHeaders for those headers and delegates to super
      for everything else). This is the pattern end-users will need.
    - 4.21 upgrade guide: extend the camel-shiro entry to document the new
      required HeaderFilterStrategy opt-in for trusted Shiro-over-transport
      routes, with a worked code example mirroring the one used in the test.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 .../ROOT/pages/camel-4x-upgrade-guide-4_21.adoc    | 38 ++++++++++++++++++++++
 .../apache/camel/itest/shiro/ShiroOverJmsTest.java | 35 ++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
index c4127f531c2e..919a78f78fdb 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
@@ -910,6 +910,44 @@ work without changes. Routes that set the header by its 
literal string value
 (for example `setHeader("SHIRO_SECURITY_USERNAME", ...)`) must be updated to
 use the new value (`setHeader("CamelShiroSecurityUsername", ...)`).
 
+Because the three header values are now in the `Camel*` namespace, transports
+that filter Camel-internal headers by default (JMS, CXF, HTTP, etc.) will
+strip the serialized Shiro authentication token before publishing. This is
+the intended behavior for untrusted producers. Trusted Shiro-over-transport
+routes that previously relied on the token surviving the boundary must opt
+those three headers back in via a custom `HeaderFilterStrategy`, for example:
+
+[source,java]
+----
+public class ShiroFriendlyJmsHeaderFilterStrategy extends 
JmsHeaderFilterStrategy {
+    @Override
+    public boolean applyFilterToCamelHeaders(String name, Object value, 
Exchange ex) {
+        if (isShiroSecurityHeader(name)) {
+            return false;
+        }
+        return super.applyFilterToCamelHeaders(name, value, ex);
+    }
+
+    @Override
+    public boolean applyFilterToExternalHeaders(String name, Object value, 
Exchange ex) {
+        if (isShiroSecurityHeader(name)) {
+            return false;
+        }
+        return super.applyFilterToExternalHeaders(name, value, ex);
+    }
+
+    private static boolean isShiroSecurityHeader(String name) {
+        return 
ShiroSecurityConstants.SHIRO_SECURITY_TOKEN.equalsIgnoreCase(name)
+                || 
ShiroSecurityConstants.SHIRO_SECURITY_USERNAME.equalsIgnoreCase(name)
+                || 
ShiroSecurityConstants.SHIRO_SECURITY_PASSWORD.equalsIgnoreCase(name);
+    }
+}
+
+jmsComponent.setHeaderFilterStrategy(new 
ShiroFriendlyJmsHeaderFilterStrategy());
+----
+
+A worked example is in `ShiroOverJmsTest` in the `camel-itest` module.
+
 
 === camel-web3j - potential breaking change
 
diff --git 
a/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java
 
b/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java
index 65f4db919560..12e104127932 100644
--- 
a/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java
+++ 
b/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java
@@ -19,8 +19,10 @@ package org.apache.camel.itest.shiro;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.jms.JmsComponent;
+import org.apache.camel.component.jms.JmsHeaderFilterStrategy;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.component.shiro.security.ShiroSecurityConstants;
 import org.apache.camel.component.shiro.security.ShiroSecurityPolicy;
@@ -63,9 +65,42 @@ public class ShiroOverJmsTest extends CamelTestSupport {
 
         amq.setCamelContext(context);
 
+        // After CAMEL-23592 the Shiro security headers live in the 
CamelShiroSecurity* namespace,
+        // which the default JmsHeaderFilterStrategy filters at the transport 
boundary. For a
+        // trusted Shiro-over-JMS route, the operator must opt those three 
headers back in.
+        amq.setHeaderFilterStrategy(new 
ShiroFriendlyJmsHeaderFilterStrategy());
+
         registry.bind("jms", amq);
     }
 
+    /**
+     * Allows the three Shiro security headers (token, username, password) to 
cross the JMS transport boundary while
+     * still filtering every other Camel-internal header.
+     */
+    private static final class ShiroFriendlyJmsHeaderFilterStrategy extends 
JmsHeaderFilterStrategy {
+        @Override
+        public boolean applyFilterToCamelHeaders(String headerName, Object 
headerValue, Exchange exchange) {
+            if (isShiroSecurityHeader(headerName)) {
+                return false;
+            }
+            return super.applyFilterToCamelHeaders(headerName, headerValue, 
exchange);
+        }
+
+        @Override
+        public boolean applyFilterToExternalHeaders(String headerName, Object 
headerValue, Exchange exchange) {
+            if (isShiroSecurityHeader(headerName)) {
+                return false;
+            }
+            return super.applyFilterToExternalHeaders(headerName, headerValue, 
exchange);
+        }
+
+        private static boolean isShiroSecurityHeader(String headerName) {
+            return 
ShiroSecurityConstants.SHIRO_SECURITY_TOKEN.equalsIgnoreCase(headerName)
+                    || 
ShiroSecurityConstants.SHIRO_SECURITY_USERNAME.equalsIgnoreCase(headerName)
+                    || 
ShiroSecurityConstants.SHIRO_SECURITY_PASSWORD.equalsIgnoreCase(headerName);
+        }
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {

Reply via email to