diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java index a40c7b07..3fa3c459 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java @@ -20,7 +20,6 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -109,7 +108,7 @@ public final class OidcLogoutAuthenticationProvider implements AuthenticationPro } if (StringUtils.hasText(oidcLogoutAuthentication.getClientId()) && !oidcLogoutAuthentication.getClientId().equals(registeredClient.getClientId())) { - throwError(OAuth2ErrorCodes.INVALID_TOKEN, OAuth2ParameterNames.CLIENT_ID); + throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.CLIENT_ID); } if (StringUtils.hasText(oidcLogoutAuthentication.getPostLogoutRedirectUri()) && !registeredClient.getPostLogoutRedirectUris().contains(oidcLogoutAuthentication.getPostLogoutRedirectUri())) { @@ -121,8 +120,8 @@ public final class OidcLogoutAuthenticationProvider implements AuthenticationPro } // Validate user identity - Authentication userPrincipal = (Authentication) oidcLogoutAuthentication.getPrincipal(); - if (isPrincipalAuthenticated(userPrincipal)) { + if (oidcLogoutAuthentication.isPrincipalAuthenticated()) { + Authentication userPrincipal = (Authentication) oidcLogoutAuthentication.getPrincipal(); if (!StringUtils.hasText(idToken.getSubject()) || !idToken.getSubject().equals(userPrincipal.getName())) { throwError(OAuth2ErrorCodes.INVALID_TOKEN, IdTokenClaimNames.SUB); @@ -146,7 +145,7 @@ public final class OidcLogoutAuthenticationProvider implements AuthenticationPro this.logger.trace("Authenticated logout request"); } - return new OidcLogoutAuthenticationToken(idToken, userPrincipal, + return new OidcLogoutAuthenticationToken(idToken, (Authentication) oidcLogoutAuthentication.getPrincipal(), oidcLogoutAuthentication.getSessionId(), oidcLogoutAuthentication.getClientId(), oidcLogoutAuthentication.getPostLogoutRedirectUri(), oidcLogoutAuthentication.getState()); } @@ -156,12 +155,6 @@ public final class OidcLogoutAuthenticationProvider implements AuthenticationPro return OidcLogoutAuthenticationToken.class.isAssignableFrom(authentication); } - private static boolean isPrincipalAuthenticated(Authentication principal) { - return principal != null && - !AnonymousAuthenticationToken.class.isAssignableFrom(principal.getClass()) && - principal.isAuthenticated(); - } - private SessionInformation findSessionInformation(Authentication principal, String sessionId) { List sessions = this.sessionRegistry.getAllSessions(principal.getPrincipal(), true); SessionInformation sessionInformation = null; diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationToken.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationToken.java index 5e3d0698..1e086c1b 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationToken.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationToken.java @@ -19,6 +19,7 @@ import java.util.Collections; import org.springframework.lang.Nullable; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.server.authorization.util.SpringAuthorizationServerVersion; @@ -102,6 +103,16 @@ public class OidcLogoutAuthenticationToken extends AbstractAuthenticationToken { return this.principal; } + /** + * Returns {@code true} if {@link #getPrincipal()} is authenticated, {@code false} otherwise. + * + * @return {@code true} if {@link #getPrincipal()} is authenticated, {@code false} otherwise + */ + public boolean isPrincipalAuthenticated() { + return !AnonymousAuthenticationToken.class.isAssignableFrom(this.principal.getClass()) && + this.principal.isAuthenticated(); + } + @Override public Object getCredentials() { return ""; diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcLogoutEndpointFilter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcLogoutEndpointFilter.java index b0cc3eea..b2d102eb 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcLogoutEndpointFilter.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcLogoutEndpointFilter.java @@ -26,7 +26,6 @@ import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.log.LogMessage; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -183,7 +182,8 @@ public final class OidcLogoutEndpointFilter extends OncePerRequestFilter { OidcLogoutAuthenticationToken oidcLogoutAuthentication = (OidcLogoutAuthenticationToken) authentication; // Check for active user session - if (isSessionActive(oidcLogoutAuthentication)) { + if (oidcLogoutAuthentication.isPrincipalAuthenticated() && + StringUtils.hasText(oidcLogoutAuthentication.getSessionId())) { // Perform logout this.logoutHandler.logout(request, response, (Authentication) oidcLogoutAuthentication.getPrincipal()); @@ -216,15 +216,4 @@ public final class OidcLogoutEndpointFilter extends OncePerRequestFilter { response.sendError(HttpStatus.BAD_REQUEST.value(), error.toString()); } - private static boolean isSessionActive(OidcLogoutAuthenticationToken oidcLogoutAuthentication) { - return isPrincipalAuthenticated((Authentication) oidcLogoutAuthentication.getPrincipal()) && - StringUtils.hasText(oidcLogoutAuthentication.getSessionId()); - } - - private static boolean isPrincipalAuthenticated(Authentication principal) { - return principal != null && - !AnonymousAuthenticationToken.class.isAssignableFrom(principal.getClass()) && - principal.isAuthenticated(); - } - } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProviderTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProviderTests.java index 4928f4c1..bcb00451 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProviderTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProviderTests.java @@ -230,7 +230,7 @@ public class OidcLogoutAuthenticationProviderTests { .isInstanceOf(OAuth2AuthenticationException.class) .extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) .satisfies(error -> { - assertThat(error.getErrorCode()).isEqualTo(OAuth2ErrorCodes.INVALID_TOKEN); + assertThat(error.getErrorCode()).isEqualTo(OAuth2ErrorCodes.INVALID_REQUEST); assertThat(error.getDescription()).contains(OAuth2ParameterNames.CLIENT_ID); }); verify(this.authorizationService).findByToken(