From c8cc9717c9e3d6f40285702badfdf63aabd14a9d Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Fri, 21 Feb 2020 16:47:24 -0500 Subject: [PATCH] Fix package tangles Issue #7699 #7840 --- ...tServiceOAuth2AuthorizedClientManager.java | 12 +- ...ReactiveOAuth2AuthorizedClientManager.java | 13 +-- ...entialsOAuth2AuthorizedClientProvider.java | 12 +- ...eactiveOAuth2AuthorizedClientProvider.java | 5 +- ...asswordOAuth2AuthorizedClientProvider.java | 12 +- ...eactiveOAuth2AuthorizedClientProvider.java | 5 +- ...shTokenOAuth2AuthorizedClientProvider.java | 12 +- ...eactiveOAuth2AuthorizedClientProvider.java | 5 +- ...ientOAuth2AuthorizationFailureHandler.java | 80 +++++-------- ...tiveOAuth2AuthorizationFailureHandler.java | 107 +++++++----------- ...activeOAuth2AccessTokenResponseClient.java | 31 ----- ...tAuthorizationCodeTokenResponseClient.java | 24 +--- ...tClientCredentialsTokenResponseClient.java | 24 +--- .../DefaultPasswordTokenResponseClient.java | 24 +--- ...efaultRefreshTokenTokenResponseClient.java | 24 +--- ...sAuthorizationCodeTokenResponseClient.java | 22 +--- .../DefaultOAuth2AuthorizedClientManager.java | 15 ++- ...ReactiveOAuth2AuthorizedClientManager.java | 14 ++- ...ientOAuth2AuthorizationSuccessHandler.java | 77 ------------- ...tiveOAuth2AuthorizationSuccessHandler.java | 80 ------------- ...uthorizedClientExchangeFilterFunction.java | 12 +- ...uthorizedClientExchangeFilterFunction.java | 9 +- ...iceOAuth2AuthorizedClientManagerTests.java | 14 ++- ...orizationCodeTokenResponseClientTests.java | 13 ++- ...ntCredentialsTokenResponseClientTests.java | 13 ++- ...ctivePasswordTokenResponseClientTests.java | 16 +-- ...eRefreshTokenTokenResponseClientTests.java | 14 +-- ...ultOAuth2AuthorizedClientManagerTests.java | 16 ++- 28 files changed, 236 insertions(+), 469 deletions(-) rename oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/{web => }/RemoveAuthorizedClientOAuth2AuthorizationFailureHandler.java (61%) rename oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/{web => }/RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler.java (51%) delete mode 100644 oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientOAuth2AuthorizationSuccessHandler.java delete mode 100644 oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler.java diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManager.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManager.java index 1eebc93a28..168551ba16 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManager.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManager.java @@ -20,8 +20,6 @@ import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager; -import org.springframework.security.oauth2.client.web.RemoveAuthorizedClientOAuth2AuthorizationFailureHandler; -import org.springframework.security.oauth2.client.web.SaveAuthorizedClientOAuth2AuthorizationSuccessHandler; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; @@ -94,8 +92,11 @@ public final class AuthorizedClientServiceOAuth2AuthorizedClientManager implemen this.clientRegistrationRepository = clientRegistrationRepository; this.authorizedClientService = authorizedClientService; this.contextAttributesMapper = new DefaultContextAttributesMapper(); - this.authorizationSuccessHandler = new SaveAuthorizedClientOAuth2AuthorizationSuccessHandler(authorizedClientService); - this.authorizationFailureHandler = new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(authorizedClientService); + this.authorizationSuccessHandler = (authorizedClient, principal, attributes) -> + authorizedClientService.saveAuthorizedClient(authorizedClient, principal); + this.authorizationFailureHandler = new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + authorizedClientService.removeAuthorizedClient(clientRegistrationId, principal.getName())); } @Nullable @@ -177,10 +178,9 @@ public final class AuthorizedClientServiceOAuth2AuthorizedClientManager implemen * Sets the {@link OAuth2AuthorizationSuccessHandler} that handles successful authorizations. * *

- * A {@link SaveAuthorizedClientOAuth2AuthorizationSuccessHandler} is used by default. + * The default saves {@link OAuth2AuthorizedClient}s in the {@link OAuth2AuthorizedClientService}. * * @param authorizationSuccessHandler the {@link OAuth2AuthorizationSuccessHandler} that handles successful authorizations - * @see SaveAuthorizedClientOAuth2AuthorizationSuccessHandler * @since 5.3 */ public void setAuthorizationSuccessHandler(OAuth2AuthorizationSuccessHandler authorizationSuccessHandler) { diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager.java index d78d8a556e..70393299b8 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager.java @@ -18,8 +18,6 @@ package org.springframework.security.oauth2.client; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager; -import org.springframework.security.oauth2.client.web.RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler; -import org.springframework.security.oauth2.client.web.SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.util.Assert; import org.springframework.web.server.ServerWebExchange; @@ -91,8 +89,11 @@ public final class AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager Assert.notNull(authorizedClientService, "authorizedClientService cannot be null"); this.clientRegistrationRepository = clientRegistrationRepository; this.authorizedClientService = authorizedClientService; - this.authorizationSuccessHandler = new SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler(authorizedClientService); - this.authorizationFailureHandler = new RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler(authorizedClientService); + this.authorizationSuccessHandler = (authorizedClient, principal, attributes) -> + authorizedClientService.saveAuthorizedClient(authorizedClient, principal); + this.authorizationFailureHandler = new RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + this.authorizedClientService.removeAuthorizedClient(clientRegistrationId, principal.getName())); } @Override @@ -179,11 +180,9 @@ public final class AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager /** * Sets the handler that handles successful authorizations. * - *

A {@link SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler} - * is used by default.

+ * The default saves {@link OAuth2AuthorizedClient}s in the {@link ReactiveOAuth2AuthorizedClientService}. * * @param authorizationSuccessHandler the handler that handles successful authorizations. - * @see SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler * @since 5.3 */ public void setAuthorizationSuccessHandler(ReactiveOAuth2AuthorizationSuccessHandler authorizationSuccessHandler) { diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsOAuth2AuthorizedClientProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsOAuth2AuthorizedClientProvider.java index a1e8d97bdb..3e50fb6747 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsOAuth2AuthorizedClientProvider.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsOAuth2AuthorizedClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentia import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.util.Assert; @@ -79,8 +80,13 @@ public final class ClientCredentialsOAuth2AuthorizedClientProvider implements OA OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest = new OAuth2ClientCredentialsGrantRequest(clientRegistration); - OAuth2AccessTokenResponse tokenResponse = - this.accessTokenResponseClient.getTokenResponse(clientCredentialsGrantRequest); + + OAuth2AccessTokenResponse tokenResponse; + try { + tokenResponse = this.accessTokenResponseClient.getTokenResponse(clientCredentialsGrantRequest); + } catch (OAuth2AuthorizationException ex) { + throw new ClientAuthorizationException(ex.getError(), clientRegistration.getRegistrationId(), ex); + } return new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(), tokenResponse.getAccessToken()); } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsReactiveOAuth2AuthorizedClientProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsReactiveOAuth2AuthorizedClientProvider.java index 67343b2095..c4e9352ef2 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsReactiveOAuth2AuthorizedClientProvider.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ClientCredentialsReactiveOAuth2AuthorizedClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.springframework.security.oauth2.client.endpoint.WebClientReactiveClie import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.util.Assert; import reactor.core.publisher.Mono; @@ -77,6 +78,8 @@ public final class ClientCredentialsReactiveOAuth2AuthorizedClientProvider imple return Mono.just(new OAuth2ClientCredentialsGrantRequest(clientRegistration)) .flatMap(this.accessTokenResponseClient::getTokenResponse) + .onErrorMap(OAuth2AuthorizationException.class, + e -> new ClientAuthorizationException(e.getError(), clientRegistration.getRegistrationId(), e)) .map(tokenResponse -> new OAuth2AuthorizedClient( clientRegistration, context.getPrincipal().getName(), tokenResponse.getAccessToken())); } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProvider.java index 67e34e29a5..91cd6e81ff 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProvider.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRe import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -96,8 +97,13 @@ public final class PasswordOAuth2AuthorizedClientProvider implements OAuth2Autho OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration, username, password); - OAuth2AccessTokenResponse tokenResponse = - this.accessTokenResponseClient.getTokenResponse(passwordGrantRequest); + + OAuth2AccessTokenResponse tokenResponse; + try { + tokenResponse = this.accessTokenResponseClient.getTokenResponse(passwordGrantRequest); + } catch (OAuth2AuthorizationException ex) { + throw new ClientAuthorizationException(ex.getError(), clientRegistration.getRegistrationId(), ex); + } return new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(), tokenResponse.getAccessToken(), tokenResponse.getRefreshToken()); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProvider.java index 7190d60f10..c8a7f5ae4e 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProvider.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.springframework.security.oauth2.client.endpoint.WebClientReactivePass import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import reactor.core.publisher.Mono; @@ -97,6 +98,8 @@ public final class PasswordReactiveOAuth2AuthorizedClientProvider implements Rea return Mono.just(passwordGrantRequest) .flatMap(this.accessTokenResponseClient::getTokenResponse) + .onErrorMap(OAuth2AuthorizationException.class, + e -> new ClientAuthorizationException(e.getError(), clientRegistration.getRegistrationId(), e)) .map(tokenResponse -> new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(), tokenResponse.getAccessToken(), tokenResponse.getRefreshToken())); } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenOAuth2AuthorizedClientProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenOAuth2AuthorizedClientProvider.java index 08f3a9bc01..310e2a6cb1 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenOAuth2AuthorizedClientProvider.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenOAuth2AuthorizedClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResp import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest; import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.util.Assert; @@ -86,8 +87,13 @@ public final class RefreshTokenOAuth2AuthorizedClientProvider implements OAuth2A OAuth2RefreshTokenGrantRequest refreshTokenGrantRequest = new OAuth2RefreshTokenGrantRequest( authorizedClient.getClientRegistration(), authorizedClient.getAccessToken(), authorizedClient.getRefreshToken(), scopes); - OAuth2AccessTokenResponse tokenResponse = - this.accessTokenResponseClient.getTokenResponse(refreshTokenGrantRequest); + + OAuth2AccessTokenResponse tokenResponse; + try { + tokenResponse = this.accessTokenResponseClient.getTokenResponse(refreshTokenGrantRequest); + } catch (OAuth2AuthorizationException ex) { + throw new ClientAuthorizationException(ex.getError(), authorizedClient.getClientRegistration().getRegistrationId(), ex); + } return new OAuth2AuthorizedClient(context.getAuthorizedClient().getClientRegistration(), context.getPrincipal().getName(), tokenResponse.getAccessToken(), tokenResponse.getRefreshToken()); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenReactiveOAuth2AuthorizedClientProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenReactiveOAuth2AuthorizedClientProvider.java index 145a637a0b..8a2203cdf9 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenReactiveOAuth2AuthorizedClientProvider.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RefreshTokenReactiveOAuth2AuthorizedClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.springframework.security.oauth2.client.endpoint.WebClientReactiveRefr import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.util.Assert; import reactor.core.publisher.Mono; @@ -88,6 +89,8 @@ public final class RefreshTokenReactiveOAuth2AuthorizedClientProvider implements return Mono.just(refreshTokenGrantRequest) .flatMap(this.accessTokenResponseClient::getTokenResponse) + .onErrorMap(OAuth2AuthorizationException.class, + e -> new ClientAuthorizationException(e.getError(), clientRegistration.getRegistrationId(), e)) .map(tokenResponse -> new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(), tokenResponse.getAccessToken(), tokenResponse.getRefreshToken())); } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/RemoveAuthorizedClientOAuth2AuthorizationFailureHandler.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RemoveAuthorizedClientOAuth2AuthorizationFailureHandler.java similarity index 61% rename from oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/RemoveAuthorizedClientOAuth2AuthorizationFailureHandler.java rename to oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RemoveAuthorizedClientOAuth2AuthorizationFailureHandler.java index f2c424b9dd..1afe7f43d1 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/RemoveAuthorizedClientOAuth2AuthorizationFailureHandler.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RemoveAuthorizedClientOAuth2AuthorizationFailureHandler.java @@ -13,19 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.oauth2.client.web; +package org.springframework.security.oauth2.client; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.ClientAuthorizationException; -import org.springframework.security.oauth2.client.OAuth2AuthorizationFailureHandler; -import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; -import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; +import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.util.Assert; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -34,8 +30,8 @@ import java.util.Set; /** * An {@link OAuth2AuthorizationFailureHandler} that removes an {@link OAuth2AuthorizedClient} - * from an {@link OAuth2AuthorizedClientRepository} or {@link OAuth2AuthorizedClientService} - * for a specific set of OAuth 2.0 error codes. + * when the {@link OAuth2Error#getErrorCode()} matches + * one of the configured {@link OAuth2ErrorCodes OAuth 2.0 error codes}. * * @author Joe Grandja * @since 5.3 @@ -74,73 +70,58 @@ public class RemoveAuthorizedClientOAuth2AuthorizationFailureHandler implements private final Set removeAuthorizedClientErrorCodes; /** - * A delegate that removes an {@link OAuth2AuthorizedClient} from a + * A delegate that removes an {@link OAuth2AuthorizedClient} from an * {@link OAuth2AuthorizedClientRepository} or {@link OAuth2AuthorizedClientService} * if the error code is one of the {@link #removeAuthorizedClientErrorCodes}. */ private final OAuth2AuthorizedClientRemover delegate; + /** + * Removes an {@link OAuth2AuthorizedClient} from an + * {@link OAuth2AuthorizedClientRepository} or {@link OAuth2AuthorizedClientService}. + */ @FunctionalInterface - private interface OAuth2AuthorizedClientRemover { + public interface OAuth2AuthorizedClientRemover { + + /** + * Removes the {@link OAuth2AuthorizedClient} associated to the + * provided client registration identifier and End-User {@link Authentication} (Resource Owner). + * + * @param clientRegistrationId the identifier for the client's registration + * @param principal the End-User {@link Authentication} (Resource Owner) + * @param attributes an immutable {@code Map} of (optional) attributes present under certain conditions. + * For example, this might contain a {@code javax.servlet.http.HttpServletRequest} + * and {@code javax.servlet.http.HttpServletResponse} if the authorization was performed + * within the context of a {@code javax.servlet.ServletContext}. + */ void removeAuthorizedClient(String clientRegistrationId, Authentication principal, Map attributes); } /** * Constructs a {@code RemoveAuthorizedClientOAuth2AuthorizationFailureHandler} using the provided parameters. * - * @param authorizedClientRepository the repository from which authorized clients will be removed - * if the error code is one of the {@link #DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES}. - */ - public RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(OAuth2AuthorizedClientRepository authorizedClientRepository) { - this(authorizedClientRepository, DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES); - } - - /** - * Constructs a {@code RemoveAuthorizedClientOAuth2AuthorizationFailureHandler} using the provided parameters. - * - * @param authorizedClientRepository the repository from which authorized clients will be removed - * if the error code is one of the {@link #removeAuthorizedClientErrorCodes}. - * @param removeAuthorizedClientErrorCodes the OAuth 2.0 error codes which will trigger removal of an authorized client. - * @see OAuth2ErrorCodes - */ - public RemoveAuthorizedClientOAuth2AuthorizationFailureHandler( - OAuth2AuthorizedClientRepository authorizedClientRepository, - Set removeAuthorizedClientErrorCodes) { - Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null"); - Assert.notNull(removeAuthorizedClientErrorCodes, "removeAuthorizedClientErrorCodes cannot be null"); - this.removeAuthorizedClientErrorCodes = Collections.unmodifiableSet(new HashSet<>(removeAuthorizedClientErrorCodes)); - this.delegate = (clientRegistrationId, principal, attributes) -> - authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal, - (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), - (HttpServletResponse) attributes.get(HttpServletResponse.class.getName())); - } - - /** - * Constructs a {@code RemoveAuthorizedClientOAuth2AuthorizationFailureHandler} using the provided parameters. - * - * @param authorizedClientService the service from which authorized clients will be removed + * @param authorizedClientRemover the {@link OAuth2AuthorizedClientRemover} used for removing an {@link OAuth2AuthorizedClient} * if the error code is one of the {@link #DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES}. */ - public RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(OAuth2AuthorizedClientService authorizedClientService) { - this(authorizedClientService, DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES); + public RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(OAuth2AuthorizedClientRemover authorizedClientRemover) { + this(authorizedClientRemover, DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES); } /** * Constructs a {@code RemoveAuthorizedClientOAuth2AuthorizationFailureHandler} using the provided parameters. * - * @param authorizedClientService the service from which authorized clients will be removed + * @param authorizedClientRemover the {@link OAuth2AuthorizedClientRemover} used for removing an {@link OAuth2AuthorizedClient} * if the error code is one of the {@link #removeAuthorizedClientErrorCodes}. * @param removeAuthorizedClientErrorCodes the OAuth 2.0 error codes which will trigger removal of an authorized client. * @see OAuth2ErrorCodes */ public RemoveAuthorizedClientOAuth2AuthorizationFailureHandler( - OAuth2AuthorizedClientService authorizedClientService, + OAuth2AuthorizedClientRemover authorizedClientRemover, Set removeAuthorizedClientErrorCodes) { - Assert.notNull(authorizedClientService, "authorizedClientService cannot be null"); + Assert.notNull(authorizedClientRemover, "authorizedClientRemover cannot be null"); Assert.notNull(removeAuthorizedClientErrorCodes, "removeAuthorizedClientErrorCodes cannot be null"); this.removeAuthorizedClientErrorCodes = Collections.unmodifiableSet(new HashSet<>(removeAuthorizedClientErrorCodes)); - this.delegate = (clientRegistrationId, principal, attributes) -> - authorizedClientService.removeAuthorizedClient(clientRegistrationId, principal.getName()); + this.delegate = authorizedClientRemover; } @Override @@ -149,6 +130,7 @@ public class RemoveAuthorizedClientOAuth2AuthorizationFailureHandler implements if (authorizationException instanceof ClientAuthorizationException && hasRemovalErrorCode(authorizationException)) { + ClientAuthorizationException clientAuthorizationException = (ClientAuthorizationException) authorizationException; this.delegate.removeAuthorizedClient( clientAuthorizationException.getClientRegistrationId(), principal, attributes); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler.java similarity index 51% rename from oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler.java rename to oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler.java index 35924d4f22..a0106ab40f 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler.java @@ -13,17 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.oauth2.client.web; +package org.springframework.security.oauth2.client; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.ClientAuthorizationException; -import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizationFailureHandler; -import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; +import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.util.Assert; -import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.util.Arrays; @@ -33,10 +30,9 @@ import java.util.Map; import java.util.Set; /** - * An authorization failure handler that removes authorized clients from a - * {@link ServerOAuth2AuthorizedClientRepository} - * or a {@link ReactiveOAuth2AuthorizedClientService}. - * for specific OAuth 2.0 error codes. + * A {@link ReactiveOAuth2AuthorizationFailureHandler} that removes an {@link OAuth2AuthorizedClient} + * when the {@link OAuth2Error#getErrorCode()} matches + * one of the configured {@link OAuth2ErrorCodes OAuth 2.0 error codes}. * * @author Phil Clay * @since 5.3 @@ -64,10 +60,8 @@ public class RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler imp OAuth2ErrorCodes.INVALID_GRANT))); /** - * A delegate that removes clients from either a - * {@link ServerOAuth2AuthorizedClientRepository} - * or a - * {@link ReactiveOAuth2AuthorizedClientService} + * A delegate that removes an {@link OAuth2AuthorizedClient} from a + * {@link ServerOAuth2AuthorizedClientRepository} or {@link ReactiveOAuth2AuthorizedClientService} * if the error code is one of the {@link #removeAuthorizedClientErrorCodes}. */ private final OAuth2AuthorizedClientRemover delegate; @@ -78,81 +72,64 @@ public class RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler imp */ private final Set removeAuthorizedClientErrorCodes; + /** + * Removes an {@link OAuth2AuthorizedClient} from a + * {@link ServerOAuth2AuthorizedClientRepository} or {@link ReactiveOAuth2AuthorizedClientService}. + */ @FunctionalInterface - private interface OAuth2AuthorizedClientRemover { - Mono removeAuthorizedClient( - String clientRegistrationId, - Authentication principal, - Map attributes); + public interface OAuth2AuthorizedClientRemover { + + /** + * Removes the {@link OAuth2AuthorizedClient} associated to the + * provided client registration identifier and End-User {@link Authentication} (Resource Owner). + * + * @param clientRegistrationId the identifier for the client's registration + * @param principal the End-User {@link Authentication} (Resource Owner) + * @param attributes an immutable {@code Map} of extra optional attributes present under certain conditions. + * For example, this might contain a {@link org.springframework.web.server.ServerWebExchange ServerWebExchange} + * if the authorization was performed within the context of a {@code ServerWebExchange}. + * @return an empty {@link Mono} that completes after this handler has finished handling the event. + */ + Mono removeAuthorizedClient(String clientRegistrationId, Authentication principal, Map attributes); } /** - * @param authorizedClientRepository The repository from which authorized clients will be removed - * if the error code is one of the {@link #DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES}. + * Constructs a {@code RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler} using the provided parameters. + * + * @param authorizedClientRemover the {@link OAuth2AuthorizedClientRemover} used for removing an {@link OAuth2AuthorizedClient} + * if the error code is one of the {@link #DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES}. */ - public RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler(ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { - this(authorizedClientRepository, DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES); + public RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler(OAuth2AuthorizedClientRemover authorizedClientRemover) { + this(authorizedClientRemover, DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES); } /** - * @param authorizedClientRepository The repository from which authorized clients will be removed - * if the error code is one of the {@code removeAuthorizedClientErrorCodes}. - * @param removeAuthorizedClientErrorCodes the OAuth 2.0 Error Codes which will trigger removal of an authorized client. + * Constructs a {@code RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler} using the provided parameters. + * + * @param authorizedClientRemover the {@link OAuth2AuthorizedClientRemover} used for removing an {@link OAuth2AuthorizedClient} + * if the error code is one of the {@link #removeAuthorizedClientErrorCodes}. + * @param removeAuthorizedClientErrorCodes the OAuth 2.0 error codes which will trigger removal of an authorized client. * @see OAuth2ErrorCodes */ public RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler( - ServerOAuth2AuthorizedClientRepository authorizedClientRepository, + OAuth2AuthorizedClientRemover authorizedClientRemover, Set removeAuthorizedClientErrorCodes) { - Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null"); + Assert.notNull(authorizedClientRemover, "authorizedClientRemover cannot be null"); Assert.notNull(removeAuthorizedClientErrorCodes, "removeAuthorizedClientErrorCodes cannot be null"); this.removeAuthorizedClientErrorCodes = Collections.unmodifiableSet(new HashSet<>(removeAuthorizedClientErrorCodes)); - this.delegate = (clientRegistrationId, principal, attributes) -> - authorizedClientRepository.removeAuthorizedClient( - clientRegistrationId, - principal, - (ServerWebExchange) attributes.get(ServerWebExchange.class.getName())); - } - - /** - * @param authorizedClientService the service from which authorized clients will be removed - * if the error code is one of the {@link #DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES}. - */ - public RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler(ReactiveOAuth2AuthorizedClientService authorizedClientService) { - this(authorizedClientService, DEFAULT_REMOVE_AUTHORIZED_CLIENT_ERROR_CODES); - } - - /** - * @param authorizedClientService the service from which authorized clients will be removed - * if the error code is one of the {@code removeAuthorizedClientErrorCodes}. - * @param removeAuthorizedClientErrorCodes the OAuth 2.0 Error Codes which will trigger removal of an authorized client. - * @see OAuth2ErrorCodes - */ - public RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler( - ReactiveOAuth2AuthorizedClientService authorizedClientService, - Set removeAuthorizedClientErrorCodes) { - Assert.notNull(authorizedClientService, "authorizedClientService cannot be null"); - Assert.notNull(removeAuthorizedClientErrorCodes, "removeAuthorizedClientErrorCodes cannot be null"); - this.removeAuthorizedClientErrorCodes = Collections.unmodifiableSet(new HashSet<>(removeAuthorizedClientErrorCodes)); - this.delegate = (clientRegistrationId, principal, attributes) -> - authorizedClientService.removeAuthorizedClient( - clientRegistrationId, - principal.getName()); + this.delegate = authorizedClientRemover; } @Override - public Mono onAuthorizationFailure( - OAuth2AuthorizationException authorizationException, - Authentication principal, - Map attributes) { + public Mono onAuthorizationFailure(OAuth2AuthorizationException authorizationException, + Authentication principal, Map attributes) { if (authorizationException instanceof ClientAuthorizationException && hasRemovalErrorCode(authorizationException)) { ClientAuthorizationException clientAuthorizationException = (ClientAuthorizationException) authorizationException; return this.delegate.removeAuthorizedClient( - clientAuthorizationException.getClientRegistrationId(), - principal, - attributes); + clientAuthorizationException.getClientRegistrationId(), principal, attributes); } else { return Mono.empty(); } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractWebClientReactiveOAuth2AccessTokenResponseClient.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractWebClientReactiveOAuth2AccessTokenResponseClient.java index 36819178bc..2991b855a8 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractWebClientReactiveOAuth2AccessTokenResponseClient.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractWebClientReactiveOAuth2AccessTokenResponseClient.java @@ -17,10 +17,8 @@ package org.springframework.security.oauth2.client.endpoint; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; -import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.util.Assert; @@ -167,38 +165,9 @@ abstract class AbstractWebClientReactiveOAuth2AccessTokenResponseClient readTokenResponse(T grantRequest, ClientResponse response) { return response.body(oauth2AccessTokenResponse()) - .onErrorMap(OAuth2AuthorizationException.class, e -> createClientAuthorizationException( - response, - clientRegistration(grantRequest).getRegistrationId(), - e)) .map(tokenResponse -> populateTokenResponse(grantRequest, tokenResponse)); } - /** - * Wraps the given {@link OAuth2AuthorizationException} in a {@link ClientAuthorizationException} - * that provides response details, and a more descriptive exception message. - * - * @param response the token response - * @param clientRegistrationId the id of the {@link ClientRegistration} for which a token is being requested - * @param authorizationException the {@link OAuth2AuthorizationException} to wrap - * @return the {@link ClientAuthorizationException} that wraps the given {@link OAuth2AuthorizationException} - */ - private OAuth2AuthorizationException createClientAuthorizationException( - ClientResponse response, - String clientRegistrationId, - OAuth2AuthorizationException authorizationException) { - - String message = String.format("Error retrieving OAuth 2.0 Access Token (HTTP Status Code: %s) %s", - response.rawStatusCode(), - authorizationException.getError()); - - return new ClientAuthorizationException( - authorizationException.getError(), - clientRegistrationId, - message, - authorizationException); - } - /** * Populates the given {@link OAuth2AccessTokenResponse} with additional details * from the grant request. diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultAuthorizationCodeTokenResponseClient.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultAuthorizationCodeTokenResponseClient.java index a8fd73626e..174dc75e43 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultAuthorizationCodeTokenResponseClient.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultAuthorizationCodeTokenResponseClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,9 @@ import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; @@ -30,7 +30,6 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestClientResponseException; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; @@ -75,22 +74,9 @@ public final class DefaultAuthorizationCodeTokenResponseClient implements OAuth2 try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { - int statusCode = 500; - if (ex instanceof RestClientResponseException) { - statusCode = ((RestClientResponseException) ex).getRawStatusCode(); - } - OAuth2Error oauth2Error = new OAuth2Error( - INVALID_TOKEN_RESPONSE_ERROR_CODE, - "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), - null); - String message = String.format("Error retrieving OAuth 2.0 Access Token (HTTP Status Code: %s) %s", - statusCode, - oauth2Error); - throw new ClientAuthorizationException( - oauth2Error, - authorizationCodeGrantRequest.getClientRegistration().getRegistrationId(), - message, - ex); + OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, + "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); + throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultClientCredentialsTokenResponseClient.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultClientCredentialsTokenResponseClient.java index 0137a6c269..fdd5eb1e75 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultClientCredentialsTokenResponseClient.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultClientCredentialsTokenResponseClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,9 @@ import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; @@ -30,7 +30,6 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestClientResponseException; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; @@ -75,22 +74,9 @@ public final class DefaultClientCredentialsTokenResponseClient implements OAuth2 try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { - int statusCode = 500; - if (ex instanceof RestClientResponseException) { - statusCode = ((RestClientResponseException) ex).getRawStatusCode(); - } - OAuth2Error oauth2Error = new OAuth2Error( - INVALID_TOKEN_RESPONSE_ERROR_CODE, - "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), - null); - String message = String.format("Error retrieving OAuth 2.0 Access Token (HTTP Status Code: %s) %s", - statusCode, - oauth2Error); - throw new ClientAuthorizationException( - oauth2Error, - clientCredentialsGrantRequest.getClientRegistration().getRegistrationId(), - message, - ex); + OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, + "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); + throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClient.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClient.java index 11a78f51ff..e2f7180d2e 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClient.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,9 @@ import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; @@ -30,7 +30,6 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestClientResponseException; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; @@ -75,22 +74,9 @@ public final class DefaultPasswordTokenResponseClient implements OAuth2AccessTok try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { - int statusCode = 500; - if (ex instanceof RestClientResponseException) { - statusCode = ((RestClientResponseException) ex).getRawStatusCode(); - } - OAuth2Error oauth2Error = new OAuth2Error( - INVALID_TOKEN_RESPONSE_ERROR_CODE, - "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), - null); - String message = String.format("Error retrieving OAuth 2.0 Access Token (HTTP Status Code: %s) %s", - statusCode, - oauth2Error); - throw new ClientAuthorizationException( - oauth2Error, - passwordGrantRequest.getClientRegistration().getRegistrationId(), - message, - ex); + OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, + "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); + throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultRefreshTokenTokenResponseClient.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultRefreshTokenTokenResponseClient.java index 4c0dd961ab..0efd37d8eb 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultRefreshTokenTokenResponseClient.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultRefreshTokenTokenResponseClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,9 @@ import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; @@ -30,7 +30,6 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestClientResponseException; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; @@ -74,22 +73,9 @@ public final class DefaultRefreshTokenTokenResponseClient implements OAuth2Acces try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { - int statusCode = 500; - if (ex instanceof RestClientResponseException) { - statusCode = ((RestClientResponseException) ex).getRawStatusCode(); - } - OAuth2Error oauth2Error = new OAuth2Error( - INVALID_TOKEN_RESPONSE_ERROR_CODE, - "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), - null); - String message = String.format("Error retrieving OAuth 2.0 Access Token (HTTP Status Code: %s) %s", - statusCode, - oauth2Error); - throw new ClientAuthorizationException( - oauth2Error, - refreshTokenGrantRequest.getClientRegistration().getRegistrationId(), - message, - ex); + OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, + "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); + throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/NimbusAuthorizationCodeTokenResponseClient.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/NimbusAuthorizationCodeTokenResponseClient.java index 83d63c53d9..cac276aa67 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/NimbusAuthorizationCodeTokenResponseClient.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/NimbusAuthorizationCodeTokenResponseClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,10 +31,10 @@ import com.nimbusds.oauth2.sdk.auth.Secret; import com.nimbusds.oauth2.sdk.http.HTTPRequest; import com.nimbusds.oauth2.sdk.id.ClientID; import org.springframework.http.MediaType; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; @@ -100,19 +100,9 @@ public class NimbusAuthorizationCodeTokenResponseClient implements OAuth2AccessT httpRequest.setReadTimeout(30000); tokenResponse = com.nimbusds.oauth2.sdk.TokenResponse.parse(httpRequest.send()); } catch (ParseException | IOException ex) { - int statusCode = 500; - OAuth2Error oauth2Error = new OAuth2Error( - INVALID_TOKEN_RESPONSE_ERROR_CODE, - "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), - null); - String message = String.format("Error retrieving OAuth 2.0 Access Token (HTTP Status Code: %s) %s", - statusCode, - oauth2Error); - throw new ClientAuthorizationException( - oauth2Error, - clientRegistration.getRegistrationId(), - message, - ex); + OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, + "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); + throw new OAuth2AuthorizationException(oauth2Error, ex); } if (!tokenResponse.indicatesSuccess()) { @@ -127,7 +117,7 @@ public class NimbusAuthorizationCodeTokenResponseClient implements OAuth2AccessT errorObject.getDescription(), errorObject.getURI() != null ? errorObject.getURI().toString() : null); } - throw new ClientAuthorizationException(oauth2Error, clientRegistration.getRegistrationId()); + throw new OAuth2AuthorizationException(oauth2Error); } AccessTokenResponse accessTokenResponse = (AccessTokenResponse) tokenResponse; diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java index ad00e66a86..2da4ab8af5 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java @@ -25,6 +25,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; +import org.springframework.security.oauth2.client.RemoveAuthorizedClientOAuth2AuthorizationFailureHandler; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; @@ -102,8 +103,15 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori this.clientRegistrationRepository = clientRegistrationRepository; this.authorizedClientRepository = authorizedClientRepository; this.contextAttributesMapper = new DefaultContextAttributesMapper(); - this.authorizationSuccessHandler = new SaveAuthorizedClientOAuth2AuthorizationSuccessHandler(authorizedClientRepository); - this.authorizationFailureHandler = new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(authorizedClientRepository); + this.authorizationSuccessHandler = (authorizedClient, principal, attributes) -> + authorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, + (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), + (HttpServletResponse) attributes.get(HttpServletResponse.class.getName())); + this.authorizationFailureHandler = new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal, + (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), + (HttpServletResponse) attributes.get(HttpServletResponse.class.getName()))); } @Nullable @@ -221,10 +229,9 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori * Sets the {@link OAuth2AuthorizationSuccessHandler} that handles successful authorizations. * *

- * A {@link SaveAuthorizedClientOAuth2AuthorizationSuccessHandler} is used by default. + * The default saves {@link OAuth2AuthorizedClient}s in the {@link OAuth2AuthorizedClientRepository}. * * @param authorizationSuccessHandler the {@link OAuth2AuthorizationSuccessHandler} that handles successful authorizations - * @see SaveAuthorizedClientOAuth2AuthorizationSuccessHandler * @since 5.3 */ public void setAuthorizationSuccessHandler(OAuth2AuthorizationSuccessHandler authorizationSuccessHandler) { diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java index eead89d565..31ba1a2b17 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java @@ -23,6 +23,7 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizationFai import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizationSuccessHandler; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider; +import org.springframework.security.oauth2.client.RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; @@ -101,8 +102,13 @@ public final class DefaultReactiveOAuth2AuthorizedClientManager implements React Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null"); this.clientRegistrationRepository = clientRegistrationRepository; this.authorizedClientRepository = authorizedClientRepository; - this.authorizationSuccessHandler = new SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler(authorizedClientRepository); - this.authorizationFailureHandler = new RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler(authorizedClientRepository); + this.authorizationSuccessHandler = (authorizedClient, principal, attributes) -> + authorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, + (ServerWebExchange) attributes.get(ServerWebExchange.class.getName())); + this.authorizationFailureHandler = new RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal, + (ServerWebExchange) attributes.get(ServerWebExchange.class.getName()))); } @Override @@ -230,11 +236,9 @@ public final class DefaultReactiveOAuth2AuthorizedClientManager implements React /** * Sets the handler that handles successful authorizations. * - *

A {@link SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler} - * is used by default.

+ * The default saves {@link OAuth2AuthorizedClient}s in the {@link ServerOAuth2AuthorizedClientRepository}. * * @param authorizationSuccessHandler the handler that handles successful authorizations. - * @see SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler * @since 5.3 */ public void setAuthorizationSuccessHandler(ReactiveOAuth2AuthorizationSuccessHandler authorizationSuccessHandler) { diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientOAuth2AuthorizationSuccessHandler.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientOAuth2AuthorizationSuccessHandler.java deleted file mode 100644 index 91647f568e..0000000000 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientOAuth2AuthorizationSuccessHandler.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.security.oauth2.client.web; - -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.OAuth2AuthorizationSuccessHandler; -import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; -import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; -import org.springframework.util.Assert; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Map; - -/** - * An {@link OAuth2AuthorizationSuccessHandler} that saves an {@link OAuth2AuthorizedClient} - * in an {@link OAuth2AuthorizedClientRepository} or {@link OAuth2AuthorizedClientService}. - * - * @author Joe Grandja - * @since 5.3 - * @see OAuth2AuthorizedClient - * @see OAuth2AuthorizedClientRepository - * @see OAuth2AuthorizedClientService - */ -public class SaveAuthorizedClientOAuth2AuthorizationSuccessHandler implements OAuth2AuthorizationSuccessHandler { - - /** - * A delegate that saves an {@link OAuth2AuthorizedClient} in an - * {@link OAuth2AuthorizedClientRepository} or {@link OAuth2AuthorizedClientService}. - */ - private final OAuth2AuthorizationSuccessHandler delegate; - - /** - * Constructs a {@code SaveAuthorizedClientOAuth2AuthorizationSuccessHandler} using the provided parameters. - * - * @param authorizedClientRepository The repository in which authorized clients will be saved. - */ - public SaveAuthorizedClientOAuth2AuthorizationSuccessHandler( - OAuth2AuthorizedClientRepository authorizedClientRepository) { - Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null"); - this.delegate = (authorizedClient, principal, attributes) -> - authorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, - (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), - (HttpServletResponse) attributes.get(HttpServletResponse.class.getName())); - } - - /** - * Constructs a {@code SaveAuthorizedClientOAuth2AuthorizationSuccessHandler} using the provided parameters. - * - * @param authorizedClientService The service in which authorized clients will be saved. - */ - public SaveAuthorizedClientOAuth2AuthorizationSuccessHandler( - OAuth2AuthorizedClientService authorizedClientService) { - Assert.notNull(authorizedClientService, "authorizedClientService cannot be null"); - this.delegate = (authorizedClient, principal, attributes) -> - authorizedClientService.saveAuthorizedClient(authorizedClient, principal); - } - - @Override - public void onAuthorizationSuccess(OAuth2AuthorizedClient authorizedClient, - Authentication principal, Map attributes) { - this.delegate.onAuthorizationSuccess(authorizedClient, principal, attributes); - } -} diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler.java deleted file mode 100644 index 3eb1da0592..0000000000 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.security.oauth2.client.web; - -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; -import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizationSuccessHandler; -import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService; -import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; -import org.springframework.util.Assert; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -import java.util.Map; - -/** - * An authorization success handler that saves authorized clients in a - * {@link ServerOAuth2AuthorizedClientRepository} - * or a {@link ReactiveOAuth2AuthorizedClientService}. - * - * @author Phil Clay - * @since 5.3 - */ -public class SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler implements ReactiveOAuth2AuthorizationSuccessHandler { - - /** - * A delegate that saves clients in either a - * {@link ServerOAuth2AuthorizedClientRepository} - * or a - * {@link ReactiveOAuth2AuthorizedClientService}. - */ - private final ReactiveOAuth2AuthorizationSuccessHandler delegate; - - /** - * @param authorizedClientRepository The repository in which authorized clients will be saved. - */ - public SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler(final ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { - Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null"); - this.delegate = (authorizedClient, principal, attributes) -> - authorizedClientRepository.saveAuthorizedClient( - authorizedClient, - principal, - (ServerWebExchange) attributes.get(ServerWebExchange.class.getName())); - } - - /** - * @param authorizedClientService The service in which authorized clients will be saved. - */ - public SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler(final ReactiveOAuth2AuthorizedClientService authorizedClientService) { - Assert.notNull(authorizedClientService, "authorizedClientService cannot be null"); - this.delegate = (authorizedClient, principal, attributes) -> - authorizedClientService.saveAuthorizedClient( - authorizedClient, - principal); - } - - @Override - public Mono onAuthorizationSuccess( - OAuth2AuthorizedClient authorizedClient, - Authentication principal, - Map attributes) { - return this.delegate.onAuthorizationSuccess( - authorizedClient, - principal, - attributes); - } -} diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.java index df2a683fc1..bb7e95f988 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.java @@ -34,14 +34,13 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClient import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder; import org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2AuthorizedClientProvider; +import org.springframework.security.oauth2.client.RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest; import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager; -import org.springframework.security.oauth2.client.web.RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler; -import org.springframework.security.oauth2.client.web.SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler; import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.client.web.server.UnAuthenticatedServerOAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; @@ -191,7 +190,10 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { ReactiveOAuth2AuthorizationFailureHandler authorizationFailureHandler = - new RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler(authorizedClientRepository); + new RemoveAuthorizedClientReactiveOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal, + (ServerWebExchange) attributes.get(ServerWebExchange.class.getName()))); this.authorizedClientManager = createDefaultAuthorizedClientManager( clientRegistrationRepository, @@ -518,7 +520,9 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements ReactiveOAuth2AuthorizationFailureHandler authorizationFailureHandler) { this.clientRegistrationRepository = clientRegistrationRepository; this.authorizedClientRepository = authorizedClientRepository; - this.authorizationSuccessHandler = new SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler(authorizedClientRepository); + this.authorizationSuccessHandler = (authorizedClient, principal, attributes) -> + authorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, + (ServerWebExchange) attributes.get(ServerWebExchange.class.getName())); this.authorizationFailureHandler = authorizationFailureHandler; } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java index d6b6371a87..a9aa044598 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java @@ -31,6 +31,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider; +import org.springframework.security.oauth2.client.RemoveAuthorizedClientOAuth2AuthorizationFailureHandler; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest; @@ -38,7 +39,6 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; -import org.springframework.security.oauth2.client.web.RemoveAuthorizedClientOAuth2AuthorizationFailureHandler; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2ErrorCodes; @@ -212,8 +212,11 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction implement OAuth2AuthorizedClientRepository authorizedClientRepository) { OAuth2AuthorizationFailureHandler authorizationFailureHandler = - new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(authorizedClientRepository); - + new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal, + (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), + (HttpServletResponse) attributes.get(HttpServletResponse.class.getName()))); this.authorizedClientManager = createDefaultAuthorizedClientManager( clientRegistrationRepository, authorizedClientRepository, authorizationFailureHandler); this.defaultAuthorizedClientManager = true; diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManagerTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManagerTests.java index 31830190df..9ca0f88929 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManagerTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/AuthorizedClientServiceOAuth2AuthorizedClientManagerTests.java @@ -23,14 +23,13 @@ import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.registration.TestClientRegistrations; -import org.springframework.security.oauth2.client.web.RemoveAuthorizedClientOAuth2AuthorizationFailureHandler; -import org.springframework.security.oauth2.client.web.SaveAuthorizedClientOAuth2AuthorizationSuccessHandler; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.security.oauth2.core.TestOAuth2AccessTokens; import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import java.util.Map; import java.util.function.Function; import static org.assertj.core.api.Assertions.assertThat; @@ -70,8 +69,15 @@ public class AuthorizedClientServiceOAuth2AuthorizedClientManagerTests { this.authorizedClientService = mock(OAuth2AuthorizedClientService.class); this.authorizedClientProvider = mock(OAuth2AuthorizedClientProvider.class); this.contextAttributesMapper = mock(Function.class); - this.authorizationSuccessHandler = spy(new SaveAuthorizedClientOAuth2AuthorizationSuccessHandler(this.authorizedClientService)); - this.authorizationFailureHandler = spy(new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(this.authorizedClientService)); + this.authorizationSuccessHandler = spy(new OAuth2AuthorizationSuccessHandler() { + @Override + public void onAuthorizationSuccess(OAuth2AuthorizedClient authorizedClient, Authentication principal, Map attributes) { + authorizedClientService.saveAuthorizedClient(authorizedClient, principal); + } + }); + this.authorizationFailureHandler = spy(new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + this.authorizedClientService.removeAuthorizedClient(clientRegistrationId, principal.getName()))); this.authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager( this.clientRegistrationRepository, this.authorizedClientService); this.authorizedClientManager.setAuthorizedClientProvider(this.authorizedClientProvider); diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveAuthorizationCodeTokenResponseClientTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveAuthorizationCodeTokenResponseClientTests.java index f4d17dcc1b..afacd25d79 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveAuthorizationCodeTokenResponseClientTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveAuthorizationCodeTokenResponseClientTests.java @@ -24,10 +24,10 @@ import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.TestClientRegistrations; import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; @@ -41,7 +41,10 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * @author Rob Winch @@ -178,7 +181,7 @@ public class WebClientReactiveAuthorizationCodeTokenResponseClientTests { this.server.enqueue(jsonResponse(accessTokenErrorResponse).setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value())); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(authorizationCodeGrantRequest()).block()) - .isInstanceOfSatisfying(ClientAuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("unauthorized_client")) + .isInstanceOfSatisfying(OAuth2AuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("unauthorized_client")) .hasMessageContaining("unauthorized_client"); } @@ -189,7 +192,7 @@ public class WebClientReactiveAuthorizationCodeTokenResponseClientTests { this.server.enqueue(jsonResponse(accessTokenErrorResponse).setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value())); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(authorizationCodeGrantRequest()).block()) - .isInstanceOf(ClientAuthorizationException.class) + .isInstanceOf(OAuth2AuthorizationException.class) .hasMessageContaining("server_error"); } @@ -204,7 +207,7 @@ public class WebClientReactiveAuthorizationCodeTokenResponseClientTests { this.server.enqueue(jsonResponse(accessTokenSuccessResponse)); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(authorizationCodeGrantRequest()).block()) - .isInstanceOf(ClientAuthorizationException.class) + .isInstanceOf(OAuth2AuthorizationException.class) .hasMessageContaining("invalid_token_response"); } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java index 56549e5975..5128f7b779 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java @@ -24,17 +24,21 @@ import org.junit.Before; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.TestClientRegistrations; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientResponseException; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.validateMockitoUsage; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * @author Rob Winch @@ -157,10 +161,9 @@ public class WebClientReactiveClientCredentialsTokenResponseClientTests { OAuth2ClientCredentialsGrantRequest request = new OAuth2ClientCredentialsGrantRequest(registration); assertThatThrownBy(() -> this.client.getTokenResponse(request).block()) - .isInstanceOfSatisfying(ClientAuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) + .isInstanceOfSatisfying(OAuth2AuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) .hasMessageContaining("[invalid_token_response]") - .hasMessageContaining("Empty OAuth 2.0 Access Token Response") - .hasMessageContaining("HTTP Status Code: 301"); + .hasMessageContaining("Empty OAuth 2.0 Access Token Response"); } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClientTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClientTests.java index f1da94589f..2cef538c1e 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClientTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClientTests.java @@ -24,11 +24,11 @@ import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.TestClientRegistrations; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import java.time.Instant; @@ -148,10 +148,9 @@ public class WebClientReactivePasswordTokenResponseClientTests { this.clientRegistrationBuilder.build(), this.username, this.password); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block()) - .isInstanceOfSatisfying(ClientAuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) + .isInstanceOfSatisfying(OAuth2AuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) .hasMessageContaining("[invalid_token_response]") .hasMessageContaining("An error occurred parsing the Access Token response") - .hasMessageContaining("HTTP Status Code: 200") .hasCauseInstanceOf(Throwable.class); } @@ -188,10 +187,8 @@ public class WebClientReactivePasswordTokenResponseClientTests { this.clientRegistrationBuilder.build(), this.username, this.password); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block()) - .isInstanceOfSatisfying(ClientAuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("unauthorized_client")) - .hasMessageContaining("[unauthorized_client]") - .hasMessageContaining("Error retrieving OAuth 2.0 Access Token") - .hasMessageContaining("HTTP Status Code: 400"); + .isInstanceOfSatisfying(OAuth2AuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("unauthorized_client")) + .hasMessageContaining("[unauthorized_client]"); } @Test @@ -202,10 +199,9 @@ public class WebClientReactivePasswordTokenResponseClientTests { this.clientRegistrationBuilder.build(), this.username, this.password); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block()) - .isInstanceOfSatisfying(ClientAuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) + .isInstanceOfSatisfying(OAuth2AuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) .hasMessageContaining("[invalid_token_response]") - .hasMessageContaining("Empty OAuth 2.0 Access Token Response") - .hasMessageContaining("HTTP Status Code: 500"); + .hasMessageContaining("Empty OAuth 2.0 Access Token Response"); } private MockResponse jsonResponse(String json) { diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveRefreshTokenTokenResponseClientTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveRefreshTokenTokenResponseClientTests.java index 2eb3a680e2..272e175b9e 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveRefreshTokenTokenResponseClientTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveRefreshTokenTokenResponseClientTests.java @@ -24,11 +24,11 @@ import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.security.oauth2.client.ClientAuthorizationException; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.TestClientRegistrations; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.security.oauth2.core.TestOAuth2AccessTokens; import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens; @@ -153,7 +153,7 @@ public class WebClientReactiveRefreshTokenTokenResponseClientTests { this.clientRegistrationBuilder.build(), this.accessToken, this.refreshToken); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(refreshTokenGrantRequest).block()) - .isInstanceOf(ClientAuthorizationException.class) + .isInstanceOf(OAuth2AuthorizationException.class) .hasMessageContaining("[invalid_token_response]") .hasMessageContaining("An error occurred parsing the Access Token response") .hasCauseInstanceOf(Throwable.class); @@ -192,9 +192,8 @@ public class WebClientReactiveRefreshTokenTokenResponseClientTests { this.clientRegistrationBuilder.build(), this.accessToken, this.refreshToken); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(refreshTokenGrantRequest).block()) - .isInstanceOfSatisfying(ClientAuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("unauthorized_client")) - .hasMessageContaining("[unauthorized_client]") - .hasMessageContaining("HTTP Status Code: 400"); + .isInstanceOfSatisfying(OAuth2AuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("unauthorized_client")) + .hasMessageContaining("[unauthorized_client]"); } @Test @@ -205,10 +204,9 @@ public class WebClientReactiveRefreshTokenTokenResponseClientTests { this.clientRegistrationBuilder.build(), this.accessToken, this.refreshToken); assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(refreshTokenGrantRequest).block()) - .isInstanceOfSatisfying(ClientAuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) + .isInstanceOfSatisfying(OAuth2AuthorizationException.class, e -> assertThat(e.getError().getErrorCode()).isEqualTo("invalid_token_response")) .hasMessageContaining("[invalid_token_response]") - .hasMessageContaining("Empty OAuth 2.0 Access Token Response") - .hasMessageContaining("HTTP Status Code: 500"); + .hasMessageContaining("Empty OAuth 2.0 Access Token Response"); } private MockResponse jsonResponse(String json) { diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java index 03b2cfc063..aa13f0c879 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java @@ -29,6 +29,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizationSuccessHand import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; +import org.springframework.security.oauth2.client.RemoveAuthorizedClientOAuth2AuthorizationFailureHandler; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.registration.TestClientRegistrations; @@ -84,8 +85,19 @@ public class DefaultOAuth2AuthorizedClientManagerTests { this.authorizedClientRepository = mock(OAuth2AuthorizedClientRepository.class); this.authorizedClientProvider = mock(OAuth2AuthorizedClientProvider.class); this.contextAttributesMapper = mock(Function.class); - this.authorizationSuccessHandler = spy(new SaveAuthorizedClientOAuth2AuthorizationSuccessHandler(this.authorizedClientRepository)); - this.authorizationFailureHandler = spy(new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(this.authorizedClientRepository)); + this.authorizationSuccessHandler = spy(new OAuth2AuthorizationSuccessHandler() { + @Override + public void onAuthorizationSuccess(OAuth2AuthorizedClient authorizedClient, Authentication principal, Map attributes) { + authorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, + (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), + (HttpServletResponse) attributes.get(HttpServletResponse.class.getName())); + } + }); + this.authorizationFailureHandler = spy(new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler( + (clientRegistrationId, principal, attributes) -> + authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal, + (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), + (HttpServletResponse) attributes.get(HttpServletResponse.class.getName())))); this.authorizedClientManager = new DefaultOAuth2AuthorizedClientManager( this.clientRegistrationRepository, this.authorizedClientRepository); this.authorizedClientManager.setAuthorizedClientProvider(this.authorizedClientProvider);