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

oscerd pushed a commit to branch camel-4.14.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-4.14.x by this push:
     new a3d35e923122 [backport camel-4.14.x] CAMEL-23592: camel-shiro - align 
Exchange header constant names with Camel naming convention (#23559)
a3d35e923122 is described below

commit a3d35e9231225149f3dd45fb6c10313d85bdf518
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu May 28 16:42:42 2026 +0200

    [backport camel-4.14.x] CAMEL-23592: camel-shiro - align Exchange header 
constant names with Camel naming convention (#23559)
    
    * CAMEL-23592: camel-shiro - align Exchange header constant names with 
Camel naming convention (#23506)
    
    Renames the three Exchange header string values in ShiroSecurityConstants
    that drive Shiro authentication (SHIRO_SECURITY_TOKEN,
    SHIRO_SECURITY_USERNAME, SHIRO_SECURITY_PASSWORD) to 
CamelShiroSecurity<Name>,
    following the convention used across the rest of the Camel component catalog
    and matching the pattern established in CAMEL-23526 (camel-cxf), CAMEL-23522
    (camel-mail), CAMEL-23461 (camel-aws-bedrock), CAMEL-23532
    (camel-vertx-websocket / camel-atmosphere-websocket / camel-iggy), and
    CAMEL-23576 (camel-jira).
    
    - SHIRO_SECURITY_TOKEN: "SHIRO_SECURITY_TOKEN" -> "CamelShiroSecurityToken"
    - SHIRO_SECURITY_USERNAME: "SHIRO_SECURITY_USERNAME" -> 
"CamelShiroSecurityUsername"
    - SHIRO_SECURITY_PASSWORD: "SHIRO_SECURITY_PASSWORD" -> 
"CamelShiroSecurityPassword"
    
    These headers carry credentials and a serialized authentication token, so
    filtering them at transport boundaries by default is particularly important.
    
    The Java field names are unchanged so routes referencing the constants
    symbolically continue to work; routes using the literal string values must 
be
    updated (documented in the 4.21 upgrade guide). No tests reference the
    literal values, and the shiro adoc documentation references the constants
    symbolically.
    
    Tracker: CAMEL-23577
    
    Reported by Claude Code on behalf of Andrea Cosentino
    
    Signed-off-by: Andrea Cosentino <[email protected]>
    
    * CAMEL-23592: camel-itest - update ShiroOverJmsTest for renamed Shiro 
security headers
    
    After CAMEL-23592 the three Shiro security header values move into 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 is exactly such a trusted Shiro-over-JMS route and
    was failing on this backport branch's CI:
    
      mock://ShiroOverJmsTestError Received message count.
      Expected: <0> but was: <1>
    
    (the consumer-side ShiroSecurityPolicy could no longer read the token
    and the message ended up at the dead-letter mock). The same regression
    exists latently on main; the matching fix is in PR #23592, and PR #23552
    applies it to the 4.18.x backport.
    
    - 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, delegates to super for
      everything else). This is the pattern end-users will need.
    - 4.14 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]>
    
    ---------
    
    Signed-off-by: Andrea Cosentino <[email protected]>
    Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
 .../shiro/security/ShiroSecurityConstants.java     |  6 +-
 .../ROOT/pages/camel-4x-upgrade-guide-4_14.adoc    | 64 ++++++++++++++++++++++
 .../apache/camel/itest/shiro/ShiroOverJmsTest.java | 35 ++++++++++++
 3 files changed, 102 insertions(+), 3 deletions(-)

diff --git 
a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityConstants.java
 
b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityConstants.java
index b3b30e800efa..4f8e7d21e5ad 100644
--- 
a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityConstants.java
+++ 
b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityConstants.java
@@ -21,9 +21,9 @@ package org.apache.camel.component.shiro.security;
  */
 public final class ShiroSecurityConstants {
 
-    public static final String SHIRO_SECURITY_TOKEN = "SHIRO_SECURITY_TOKEN";
-    public static final String SHIRO_SECURITY_USERNAME = 
"SHIRO_SECURITY_USERNAME";
-    public static final String SHIRO_SECURITY_PASSWORD = 
"SHIRO_SECURITY_PASSWORD";
+    public static final String SHIRO_SECURITY_TOKEN = 
"CamelShiroSecurityToken";
+    public static final String SHIRO_SECURITY_USERNAME = 
"CamelShiroSecurityUsername";
+    public static final String SHIRO_SECURITY_PASSWORD = 
"CamelShiroSecurityPassword";
 
     private ShiroSecurityConstants() {
     }
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc
index 7e2113be5a7a..b3e3c195b2b3 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc
@@ -242,6 +242,70 @@ As a consequence, the generated Endpoint DSL header 
accessors on
 `resultClassType()` -> `arangoDbResultClassType()`.
 
 
+=== camel-shiro - potential breaking change
+
+The three Exchange header constants in `ShiroSecurityConstants` that drive
+Shiro authentication used header values outside the `Camel` namespace
+(`SHIRO_SECURITY_TOKEN`, `SHIRO_SECURITY_USERNAME`, `SHIRO_SECURITY_PASSWORD`)
+and were therefore not filtered by the default `HeaderFilterStrategy`. They
+have been renamed to follow the Camel naming convention. The Java field names
+are unchanged; only the header string values have changed:
+
+[options="header"]
+|===
+| Constant | Previous value | New value
+| `ShiroSecurityConstants.SHIRO_SECURITY_TOKEN` | `SHIRO_SECURITY_TOKEN` | 
`CamelShiroSecurityToken`
+| `ShiroSecurityConstants.SHIRO_SECURITY_USERNAME` | `SHIRO_SECURITY_USERNAME` 
| `CamelShiroSecurityUsername`
+| `ShiroSecurityConstants.SHIRO_SECURITY_PASSWORD` | `SHIRO_SECURITY_PASSWORD` 
| `CamelShiroSecurityPassword`
+|===
+
+These headers carry credentials and a serialized authentication token, so
+filtering them at transport boundaries by default is particularly important.
+
+Routes that reference the constants symbolically (for example
+`setHeader(ShiroSecurityConstants.SHIRO_SECURITY_USERNAME, ...)`) continue to
+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.
+
 == Upgrading from 4.14.5 to 4.14.6
 
 === camel-platform-http-main
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 ccd5e8b2661f..5a702f8e9da8 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;
@@ -61,9 +63,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