Class RememberMeLogoutHandlerDelegate
Component invoked by AuthenticationLogoutHandler
to revoke state related to 'remember-me'
on logout.
Note that this component itself is intentionally not a standalone LogoutHandler
- the
expectation is for this logic to be selectively invoked by AuthenticationLogoutHandler
only when a valid login exists in a state that can be revoked.
-
Constructor Summary
ConstructorsConstructorDescriptionRememberMeLogoutHandlerDelegate
(RememberMeCookieUtility rememberMeCookieUtility, RememberMeLoginProperties rememberMeLoginProperties, BroadleafPersistentTokenRememberMeServices persistentTokenRememberMeServices, RememberMeTokenEntityRepository<?> rememberMeTokenEntityRepository) -
Method Summary
Modifier and TypeMethodDescriptionprotected RememberMeCookieUtility
protected RememberMeLoginProperties
protected RememberMeTokenEntityRepository<?>
getUsernameToInvalidateTokensFor
(Map<String, Object> sessionTokenClaims) protected void
handleMissingRememberMeAutoLoginCookie
(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, org.springframework.security.core.Authentication authentication, AuthorizedClient client, AuthorizationServer authorizationServer, Map<String, Object> sessionTokenClaims) This is provided as a hook point to allow handling a scenario whereRememberMeLoginProperties.isGloballyRevokeAllUserTokensOnLogout()
is false but the logout request itself did not present a remember me cookie whose token could be directly invalidated.protected void
invalidateTokens
(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, org.springframework.security.core.Authentication authentication, AuthorizedClient client, AuthorizationServer authorizationServer, Map<String, Object> sessionTokenClaims) The default implementation inPersistentTokenBasedRememberMeServices.logout(HttpServletRequest, HttpServletResponse, Authentication)
always callsPersistentTokenRepository.removeUserTokens(String)
, which will globally invalidate all remember me tokens for a particular username.protected boolean
isImpersonatedSessionToken
(Map<String, Object> sessionTokenClaims) This logic mimicsDefaultOAuth2SessionToken.isImpersonated()
.void
logout
(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, org.springframework.security.core.Authentication authentication, AuthorizedClient client, AuthorizationServer authorizationServer, Map<String, Object> sessionTokenClaims) Method that is called to clear 'remember me' state after a user logs out.
-
Constructor Details
-
RememberMeLogoutHandlerDelegate
public RememberMeLogoutHandlerDelegate(RememberMeCookieUtility rememberMeCookieUtility, RememberMeLoginProperties rememberMeLoginProperties, BroadleafPersistentTokenRememberMeServices persistentTokenRememberMeServices, RememberMeTokenEntityRepository<?> rememberMeTokenEntityRepository)
-
-
Method Details
-
logout
public void logout(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, org.springframework.security.core.Authentication authentication, AuthorizedClient client, AuthorizationServer authorizationServer, Map<String, Object> sessionTokenClaims) Method that is called to clear 'remember me' state after a user logs out. This method is assumed to only be called on 'valid' logout requests - ex: when a login cookie was found on the request.
The implementation in here is based on
PersistentTokenBasedRememberMeServices.logout(HttpServletRequest, HttpServletResponse, Authentication)
, with a few adjustments.- Parameters:
request
- the original HTTP request passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
response
- the original HTTP response passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
authentication
- the original Authentication passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
client
- theAuthorizedClient
that this logout was determined to be happening withinauthorizationServer
- theAuthorizationServer
that this logout was determined to be happening withinsessionTokenClaims
- the claims parsed out of the session token cookie that was found on the logout request. Should always be provided.
-
invalidateTokens
protected void invalidateTokens(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, @Nullable org.springframework.security.core.Authentication authentication, AuthorizedClient client, AuthorizationServer authorizationServer, Map<String, Object> sessionTokenClaims) The default implementation in
PersistentTokenBasedRememberMeServices.logout(HttpServletRequest, HttpServletResponse, Authentication)
always callsPersistentTokenRepository.removeUserTokens(String)
, which will globally invalidate all remember me tokens for a particular username.For Broadleaf, this behavior would be inappropriate. The primary issue is that our 'remember me' tokens are distinct per-client, so logging out of one client should not mean that your 'remember me' state on other clients is revoked. Similarly, logging out on one device should not mean that your 'remember me' state on other devices is also revoked.
We expect that logout requests should include the remember-me cookie since their domain/path/etc should all match. Thus, we can grab the cookie from the request and extract its
PersistentRememberMeToken.getSeries()
. Then, we can invalidate only the token related to thatPersistentRememberMeToken.getSeries()
. The series is unique to each device/client that we log into, so by only revoking for a series, we ensure other tokens for the user remain intact.- Parameters:
request
- the original HTTP request passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
response
- the original HTTP response passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
authentication
- the original Authentication passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
. This is typicallynull
since the logout filter does not have any security on it.client
- theAuthorizedClient
that this logout was determined to be happening withinauthorizationServer
- theAuthorizationServer
that this logout was determined to be happening withinsessionTokenClaims
- the claims parsed out of the session token cookie that was found on the logout request. Should always be provided.
-
isImpersonatedSessionToken
This logic mimicsDefaultOAuth2SessionToken.isImpersonated()
.- Parameters:
sessionTokenClaims
- the session token claims- Returns:
- whether this session token represents an impersonated session
-
getUsernameToInvalidateTokensFor
-
handleMissingRememberMeAutoLoginCookie
protected void handleMissingRememberMeAutoLoginCookie(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, @Nullable org.springframework.security.core.Authentication authentication, AuthorizedClient client, AuthorizationServer authorizationServer, Map<String, Object> sessionTokenClaims) This is provided as a hook point to allow handling a scenario whereRememberMeLoginProperties.isGloballyRevokeAllUserTokensOnLogout()
is false but the logout request itself did not present a remember me cookie whose token could be directly invalidated. This can have a benign cause - for example, the user did not have a remember me cookie set in the first place. Another possibility is that the logout request was submitted in a way that could not include the cookie. In any case, clients who wish to handle this scenario can override this method to do so. By default, nothing is done.- Parameters:
request
- the original HTTP request passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
response
- the original HTTP response passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
authentication
- the original Authentication passed toAuthenticationLogoutHandler.logout(HttpServletRequest, HttpServletResponse, Authentication)
. This is typicallynull
since the logout filter does not have any security on it.client
- theAuthorizedClient
that this logout was determined to be happening withinauthorizationServer
- theAuthorizationServer
that this logout was determined to be happening withinsessionTokenClaims
- the claims parsed out of the session token cookie that was found on the logout request. Should always be provided.
-
getRememberMeCookieUtility
-
getRememberMeLoginProperties
-
getPersistentTokenRememberMeServices
-
getRememberMeTokenEntityRepository
-