mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	
							parent
							
								
									f2da2c56be
								
							
						
					
					
						commit
						c8cc9717c9
					
				| @ -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. | ||||
| 	 * | ||||
| 	 * <p> | ||||
| 	 * 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) { | ||||
|  | ||||
| @ -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. | ||||
| 	 * | ||||
| 	 * <p>A {@link SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler} | ||||
| 	 * is used by default.</p> | ||||
| 	 * 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) { | ||||
|  | ||||
| @ -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()); | ||||
| 	} | ||||
|  | ||||
| @ -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())); | ||||
| 	} | ||||
|  | ||||
| @ -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()); | ||||
|  | ||||
| @ -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())); | ||||
| 	} | ||||
|  | ||||
| @ -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()); | ||||
|  | ||||
| @ -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())); | ||||
| 	} | ||||
|  | ||||
| @ -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<String> 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<String, Object> 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<String> 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<String> 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); | ||||
| @ -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<String> removeAuthorizedClientErrorCodes; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Removes an {@link OAuth2AuthorizedClient} from a | ||||
| 	 * {@link ServerOAuth2AuthorizedClientRepository} or {@link ReactiveOAuth2AuthorizedClientService}. | ||||
| 	 */ | ||||
| 	@FunctionalInterface | ||||
| 	private interface OAuth2AuthorizedClientRemover { | ||||
| 		Mono<Void> removeAuthorizedClient( | ||||
| 				String clientRegistrationId, | ||||
| 				Authentication principal, | ||||
| 				Map<String, Object> 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<Void> removeAuthorizedClient(String clientRegistrationId, Authentication principal, Map<String, Object> 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<String> 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<String> 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<Void> onAuthorizationFailure( | ||||
| 			OAuth2AuthorizationException authorizationException, | ||||
| 			Authentication principal, | ||||
| 			Map<String, Object> attributes) { | ||||
| 	public Mono<Void> onAuthorizationFailure(OAuth2AuthorizationException authorizationException, | ||||
| 			Authentication principal, Map<String, Object> 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(); | ||||
| 		} | ||||
| @ -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<T extend | ||||
| 	 */ | ||||
| 	private Mono<OAuth2AccessTokenResponse> 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. | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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. | ||||
| 	 * | ||||
| 	 * <p> | ||||
| 	 * 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) { | ||||
|  | ||||
| @ -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. | ||||
| 	 * | ||||
| 	 * <p>A {@link SaveAuthorizedClientReactiveOAuth2AuthorizationSuccessHandler} | ||||
| 	 * is used by default.</p> | ||||
| 	 * 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) { | ||||
|  | ||||
| @ -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<String, Object> attributes) { | ||||
| 		this.delegate.onAuthorizationSuccess(authorizedClient, principal, attributes); | ||||
| 	} | ||||
| } | ||||
| @ -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<Void> onAuthorizationSuccess( | ||||
| 			OAuth2AuthorizedClient authorizedClient, | ||||
| 			Authentication principal, | ||||
| 			Map<String, Object> attributes) { | ||||
| 		return this.delegate.onAuthorizationSuccess( | ||||
| 				authorizedClient, | ||||
| 				principal, | ||||
| 				attributes); | ||||
| 	} | ||||
| } | ||||
| @ -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; | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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<String, Object> 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); | ||||
|  | ||||
| @ -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"); | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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"); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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<String, Object> 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); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user