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
}
}