From b124150d3a6288bdabc277c15b6bb1b9108414cf Mon Sep 17 00:00:00 2001 From: lprimak Date: Sat, 15 Aug 2026 12:19:38 -0500 Subject: [PATCH 1/2] enh: support for remembered principals in session management, check whether url rewriting enabled in more places --- .../apache/shiro/mgt/DefaultSecurityManager.java | 7 ++++--- .../org/apache/shiro/subject/SubjectContext.java | 13 +++++++++++++ .../subject/support/DefaultSubjectContext.java | 11 +++++++++++ .../web/session/mgt/DefaultWebSessionManager.java | 8 +++----- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java b/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java index ebf05622f1..86155b5703 100644 --- a/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java +++ b/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java @@ -379,6 +379,9 @@ public Subject createSubject(SubjectContext subjectContext) { //session, so we don't constantly rehydrate the rememberMe PrincipalCollection on every operation). //Added in 1.2: if (context.isSessionCreationEnabled()) { + if (context.isRememberedPrincipals()) { + beforeSuccessfulLogin(subject); + } save(subject); } @@ -439,7 +442,6 @@ protected void delete(Subject subject) { * @return The SubjectContext to use to pass to a {@link SubjectFactory} for subject creation. * @since 1.0 */ - @SuppressWarnings({"unchecked"}) protected SubjectContext ensureSecurityManager(SubjectContext context) { if (context.resolveSecurityManager() != null) { LOGGER.trace("Context already contains a SecurityManager instance. Returning."); @@ -463,7 +465,6 @@ protected SubjectContext ensureSecurityManager(SubjectContext context) { * @return The context to use to pass to a {@link SubjectFactory} for subject creation. * @since 1.0 */ - @SuppressWarnings({"unchecked"}) protected SubjectContext resolveSession(SubjectContext context) { if (context.resolveSession() != null) { LOGGER.debug("Context already contains a session. Returning."); @@ -518,7 +519,6 @@ private static boolean isEmpty(PrincipalCollection pc) { * @return The Subject context to use to pass to a {@link SubjectFactory} for subject creation. * @since 1.0 */ - @SuppressWarnings({"unchecked"}) protected SubjectContext resolvePrincipals(SubjectContext context) { PrincipalCollection principals = context.resolvePrincipals(); @@ -531,6 +531,7 @@ protected SubjectContext resolvePrincipals(SubjectContext context) { if (!isEmpty(principals)) { LOGGER.debug("Found remembered PrincipalCollection. Adding to the context to be used " + "for subject construction by the SubjectFactory."); + context.setRememberedPrincipals(true); context.setPrincipals(principals); diff --git a/core/src/main/java/org/apache/shiro/subject/SubjectContext.java b/core/src/main/java/org/apache/shiro/subject/SubjectContext.java index d9e29a6392..a55dcf5a12 100644 --- a/core/src/main/java/org/apache/shiro/subject/SubjectContext.java +++ b/core/src/main/java/org/apache/shiro/subject/SubjectContext.java @@ -235,4 +235,17 @@ public interface SubjectContext extends Map { void setHost(String host); String resolveHost(); + + /** + * Sets whether the constructed {@code Subject} instance should was constructed from remembered principals + */ + default void setRememberedPrincipals(boolean rememberedPrincipals) { } + + /** + * Returns whether the constructed {@code Subject} instance was constructed from remembered principals + * @return true if the constructed {@code Subject} instance was constructed from remembered principals, false otherwise + */ + default boolean isRememberedPrincipals() { + return false; + } } diff --git a/core/src/main/java/org/apache/shiro/subject/support/DefaultSubjectContext.java b/core/src/main/java/org/apache/shiro/subject/support/DefaultSubjectContext.java index 54cb73e4dc..f14612beea 100644 --- a/core/src/main/java/org/apache/shiro/subject/support/DefaultSubjectContext.java +++ b/core/src/main/java/org/apache/shiro/subject/support/DefaultSubjectContext.java @@ -79,6 +79,8 @@ public class DefaultSubjectContext extends MapContext implements SubjectContext private static final String HOST = DefaultSubjectContext.class.getName() + ".HOST"; + private static final String REMEMBERED_PRINCIPALS = DefaultSubjectContext.class.getName() + ".REMEMBERED_PRINCIPALS"; + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSubjectContext.class); public DefaultSubjectContext() { @@ -279,4 +281,13 @@ public String resolveHost() { return host; } + + public void setRememberedPrincipals(boolean remembered) { + put(REMEMBERED_PRINCIPALS, remembered); + } + + public boolean isRememberedPrincipals() { + Boolean remembered = getTypedValue(REMEMBERED_PRINCIPALS, Boolean.class); + return remembered != null && remembered; + } } diff --git a/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java b/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java index 2f00b326a2..759e41ab5c 100644 --- a/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java +++ b/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java @@ -114,11 +114,10 @@ private String getSessionIdCookieValue(ServletRequest request, ServletResponse r LOGGER.debug("Session ID cookie is disabled - session id will not be acquired from a request cookie."); return null; } - if (!(request instanceof HttpServletRequest)) { + if (!(request instanceof HttpServletRequest httpRequest)) { LOGGER.debug("Current request is not an HttpServletRequest - cannot get session ID cookie. Returning null."); return null; } - HttpServletRequest httpRequest = (HttpServletRequest) request; return getSessionIdCookie().readValue(httpRequest, WebUtils.toHttp(response)); } @@ -128,7 +127,7 @@ private Serializable getReferencedSessionId(ServletRequest request, ServletRespo if (id != null) { request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE); - } else { + } else if (isSessionIdUrlRewritingEnabled()) { //not in a cookie, or cookie is disabled - try the request URI as a fallback (i.e. due to URL rewriting): //try the URI path segment parameters first: @@ -170,10 +169,9 @@ private Serializable getReferencedSessionId(ServletRequest request, ServletRespo //since 1.2.2 private String getUriPathSegmentParamValue(ServletRequest servletRequest, String paramName) { - if (!(servletRequest instanceof HttpServletRequest)) { + if (!(servletRequest instanceof HttpServletRequest request)) { return null; } - HttpServletRequest request = (HttpServletRequest) servletRequest; String uri = request.getRequestURI(); if (uri == null) { return null; From 0d72f43b8c394e2d350389df36b5ef512640943d Mon Sep 17 00:00:00 2001 From: lprimak Date: Sat, 15 Aug 2026 16:38:19 -0500 Subject: [PATCH 2/2] chore: IllegalStateException is thrown by the default implementation, thus forcing the implementation to override it --- .../main/java/org/apache/shiro/subject/SubjectContext.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/shiro/subject/SubjectContext.java b/core/src/main/java/org/apache/shiro/subject/SubjectContext.java index a55dcf5a12..a57ec64d10 100644 --- a/core/src/main/java/org/apache/shiro/subject/SubjectContext.java +++ b/core/src/main/java/org/apache/shiro/subject/SubjectContext.java @@ -239,13 +239,15 @@ public interface SubjectContext extends Map { /** * Sets whether the constructed {@code Subject} instance should was constructed from remembered principals */ - default void setRememberedPrincipals(boolean rememberedPrincipals) { } + default void setRememberedPrincipals(boolean rememberedPrincipals) { + throw new IllegalStateException("Remembered principals are not supported by this SubjectContext implementation."); + } /** * Returns whether the constructed {@code Subject} instance was constructed from remembered principals * @return true if the constructed {@code Subject} instance was constructed from remembered principals, false otherwise */ default boolean isRememberedPrincipals() { - return false; + throw new IllegalStateException("Remembered principals are not supported by this SubjectContext implementation."); } }