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

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


The following commit(s) were added to refs/heads/main by this push:
     new 2bfec7ebf bugfix: fix security context handling in JAX-RS support for 
methods isSecure() and getAuthenticationScheme() - was throwing stack overflow 
errors
2bfec7ebf is described below

commit 2bfec7ebf97b208c0b718b39619f7ad43af86028
Author: lprimak <[email protected]>
AuthorDate: Thu Aug 20 05:34:26 2026 -0500

    bugfix: fix security context handling in JAX-RS support for methods 
isSecure() and getAuthenticationScheme() - was throwing stack overflow errors
---
 .../org/apache/shiro/testing/jaxrs/WhoamiResource.java  | 17 +++++++++++++++++
 .../org/apache/shiro/testing/jaxrs/NoIniJaxRsIT.java    | 13 +++++++++++++
 .../apache/shiro/web/jaxrs/ShiroSecurityContext.java    | 12 ++++--------
 .../web/jaxrs/SubjectPrincipalRequestFilterTest.groovy  |  2 +-
 4 files changed, 35 insertions(+), 9 deletions(-)

diff --git 
a/integration-tests/jakarta-ee/src/main/java/org/apache/shiro/testing/jaxrs/WhoamiResource.java
 
b/integration-tests/jakarta-ee/src/main/java/org/apache/shiro/testing/jaxrs/WhoamiResource.java
index eff0860b9..9a48d492d 100644
--- 
a/integration-tests/jakarta-ee/src/main/java/org/apache/shiro/testing/jaxrs/WhoamiResource.java
+++ 
b/integration-tests/jakarta-ee/src/main/java/org/apache/shiro/testing/jaxrs/WhoamiResource.java
@@ -22,9 +22,11 @@ import jakarta.ws.rs.QueryParam;
 
 import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
 
+import jakarta.ws.rs.core.Context;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.Response.Status;
 
+import jakarta.ws.rs.core.SecurityContext;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.UsernamePasswordToken;
 import org.apache.shiro.lang.ShiroException;
@@ -39,6 +41,10 @@ public class WhoamiResource {
     RolesAllowedBean rolesAllowedBean;
     @Inject
     TestApplication testApplication;
+    @Context
+    SecurityContext securityContext;
+
+    public record SecurityDetails(String principal, boolean isSecure, String 
authScheme) { }
 
     @GET
     @Path("whoami")
@@ -75,6 +81,17 @@ public class WhoamiResource {
         return check(rolesAllowedBean::permit, rolesAllowedBean::permit, user, 
password);
     }
 
+    @GET
+    @Path("securityContext")
+    @Produces(APPLICATION_JSON)
+    public Response securityContext(@QueryParam("user") String user, 
@QueryParam("password") String password) {
+        return check(() -> Response.ok(new SecurityDetails(
+                securityContext.getUserPrincipal().getName(),
+                securityContext.isSecure(),
+                securityContext.getAuthenticationScheme()
+        )).build(), () -> Response.status(Status.UNAUTHORIZED).build(), user, 
password);
+    }
+
     private <T> T check(Supplier<T> happy, Supplier<T> sad, String user, 
String password) {
         try {
             return new Subject.Builder()
diff --git 
a/integration-tests/jakarta-ee/src/test/java/org/apache/shiro/testing/jaxrs/NoIniJaxRsIT.java
 
b/integration-tests/jakarta-ee/src/test/java/org/apache/shiro/testing/jaxrs/NoIniJaxRsIT.java
index 7d93b110b..5dc1918b9 100644
--- 
a/integration-tests/jakarta-ee/src/test/java/org/apache/shiro/testing/jaxrs/NoIniJaxRsIT.java
+++ 
b/integration-tests/jakarta-ee/src/test/java/org/apache/shiro/testing/jaxrs/NoIniJaxRsIT.java
@@ -27,8 +27,10 @@ import lombok.SneakyThrows;
 import org.apache.shiro.testing.cdi.ComponentInjectionIT;
 
 import static org.apache.shiro.testing.cdi.ComponentInjectionIT.TESTABLE_MODE;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
 
+import org.apache.shiro.testing.jaxrs.WhoamiResource.SecurityDetails;
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.container.test.api.OperateOnDeployment;
 import org.jboss.arquillian.junit5.ArquillianExtension;
@@ -130,6 +132,17 @@ public class NoIniJaxRsIT {
                 .request().get().getStatus());
     }
 
+    @Test
+    @OperateOnDeployment(TESTABLE_MODE)
+    void securityContext() {
+        var securityDetails = createWebTarget("whoami/securityContext", 
Credentials.builder()
+                .username("powerful").password("awesome").send(true).build())
+                .request().get().readEntity(SecurityDetails.class);
+        assertThat(securityDetails.principal()).isEqualTo("powerful");
+        assertThat(securityDetails.isSecure()).isFalse();
+        assertThat(securityDetails.authScheme()).isNull();
+    }
+
     @Deployment(name = TESTABLE_MODE)
     public static WebArchive createDeployment() {
         return ComponentInjectionIT.createDeployment("no-ini-jaxrs.war");
diff --git 
a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java
 
b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java
index d716107dc..cbc7ca833 100644
--- 
a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java
+++ 
b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java
@@ -33,12 +33,9 @@ import java.security.Principal;
  * @since 1.4
  */
 public class ShiroSecurityContext implements SecurityContext {
-
-    private final ContainerRequestContext containerRequestContext;
     private final SecurityContext originalSecurityContext;
 
     public ShiroSecurityContext(ContainerRequestContext 
containerRequestContext) {
-        this.containerRequestContext = containerRequestContext;
         this.originalSecurityContext = 
containerRequestContext.getSecurityContext();
     }
 
@@ -69,12 +66,12 @@ public class ShiroSecurityContext implements 
SecurityContext {
 
     @Override
     public boolean isSecure() {
-        return containerRequestContext.getSecurityContext().isSecure();
+        return originalSecurityContext.isSecure();
     }
 
     @Override
     public String getAuthenticationScheme() {
-        return 
containerRequestContext.getSecurityContext().getAuthenticationScheme();
+        return originalSecurityContext.getAuthenticationScheme();
     }
 
     private Subject getSubject() {
@@ -85,9 +82,8 @@ public class ShiroSecurityContext implements SecurityContext {
     /**
      * Java Principal wrapper around any Shiro Principal object.s
      */
-    private class ObjectPrincipal implements Principal {
-
-        private Object object;
+    private static class ObjectPrincipal implements Principal {
+        private final Object object;
 
         ObjectPrincipal(Object object) {
             this.object = object;
diff --git 
a/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy
 
b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy
index a18ae5241..4bb386c3c 100644
--- 
a/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy
+++ 
b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy
@@ -48,7 +48,7 @@ class SubjectPrincipalRequestFilterTest {
         filter.filter(requestContext)
 
         verify requestContext, originalSecurityContext
-        assertSame requestContext, contextCapture.value.containerRequestContext
+        assertNotSame requestContext, 
contextCapture.value.originalSecurityContext
     }
 
 }

Reply via email to