DefaultClientCredentialsTokenResponseClient throws OAuth2AuthorizationException
Fixes gh-5726
This commit is contained in:
		
							parent
							
								
									e56c048db3
								
							
						
					
					
						commit
						56b4576396
					
				| 
						 | 
				
			
			@ -22,7 +22,7 @@ import org.springframework.http.converter.FormHttpMessageConverter;
 | 
			
		|||
import org.springframework.http.converter.HttpMessageConverter;
 | 
			
		||||
import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler;
 | 
			
		||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 | 
			
		||||
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;
 | 
			
		||||
| 
						 | 
				
			
			@ -65,9 +65,7 @@ public final class DefaultClientCredentialsTokenResponseClient implements OAuth2
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public OAuth2AccessTokenResponse getTokenResponse(OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest)
 | 
			
		||||
			throws OAuth2AuthenticationException {
 | 
			
		||||
 | 
			
		||||
	public OAuth2AccessTokenResponse getTokenResponse(OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest) {
 | 
			
		||||
		Assert.notNull(clientCredentialsGrantRequest, "clientCredentialsGrantRequest cannot be null");
 | 
			
		||||
 | 
			
		||||
		RequestEntity<?> request = this.requestEntityConverter.convert(clientCredentialsGrantRequest);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +76,7 @@ public final class DefaultClientCredentialsTokenResponseClient implements OAuth2
 | 
			
		|||
		} catch (RestClientException 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 OAuth2AuthenticationException(oauth2Error, oauth2Error.toString(), ex);
 | 
			
		||||
			throw new OAuth2AuthorizationException(oauth2Error, ex);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		OAuth2AccessTokenResponse tokenResponse = response.getBody();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ import com.nimbusds.oauth2.sdk.token.BearerTokenError;
 | 
			
		|||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.springframework.http.client.ClientHttpResponse;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 | 
			
		||||
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.http.converter.OAuth2ErrorHttpMessageConverter;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ public class OAuth2ErrorResponseErrorHandler implements ResponseErrorHandler {
 | 
			
		|||
			oauth2Error = this.oauth2ErrorConverter.read(OAuth2Error.class, response);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
 | 
			
		||||
		throw new OAuth2AuthorizationException(oauth2Error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private OAuth2Error readErrorFromWwwAuthenticate(HttpHeaders headers) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
 | 
			
		|||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
 | 
			
		||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
 | 
			
		||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
 | 
			
		||||
 | 
			
		||||
import java.time.Instant;
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +169,7 @@ public class DefaultClientCredentialsTokenResponseClientTests {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getTokenResponseWhenSuccessResponseAndNotBearerTokenTypeThenThrowOAuth2AuthenticationException() {
 | 
			
		||||
	public void getTokenResponseWhenSuccessResponseAndNotBearerTokenTypeThenThrowOAuth2AuthorizationException() {
 | 
			
		||||
		String accessTokenSuccessResponse = "{\n" +
 | 
			
		||||
				"	\"access_token\": \"access-token-1234\",\n" +
 | 
			
		||||
				"   \"token_type\": \"not-bearer\",\n" +
 | 
			
		||||
| 
						 | 
				
			
			@ -181,13 +181,13 @@ public class DefaultClientCredentialsTokenResponseClientTests {
 | 
			
		|||
				new OAuth2ClientCredentialsGrantRequest(this.clientRegistration);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(clientCredentialsGrantRequest))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessageContaining("[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response")
 | 
			
		||||
				.hasMessageContaining("tokenType cannot be null");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getTokenResponseWhenSuccessResponseAndMissingTokenTypeParameterThenThrowOAuth2AuthenticationException() {
 | 
			
		||||
	public void getTokenResponseWhenSuccessResponseAndMissingTokenTypeParameterThenThrowOAuth2AuthorizationException() {
 | 
			
		||||
		String accessTokenSuccessResponse = "{\n" +
 | 
			
		||||
				"	\"access_token\": \"access-token-1234\"\n" +
 | 
			
		||||
				"}\n";
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +197,7 @@ public class DefaultClientCredentialsTokenResponseClientTests {
 | 
			
		|||
				new OAuth2ClientCredentialsGrantRequest(this.clientRegistration);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(clientCredentialsGrantRequest))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessageContaining("[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response")
 | 
			
		||||
				.hasMessageContaining("tokenType cannot be null");
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +238,7 @@ public class DefaultClientCredentialsTokenResponseClientTests {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getTokenResponseWhenTokenUriInvalidThenThrowOAuth2AuthenticationException() {
 | 
			
		||||
	public void getTokenResponseWhenTokenUriInvalidThenThrowOAuth2AuthorizationException() {
 | 
			
		||||
		String invalidTokenUri = "http://invalid-provider.com/oauth2/token";
 | 
			
		||||
		ClientRegistration clientRegistration = this.from(this.clientRegistration)
 | 
			
		||||
				.tokenUri(invalidTokenUri)
 | 
			
		||||
| 
						 | 
				
			
			@ -248,12 +248,12 @@ public class DefaultClientCredentialsTokenResponseClientTests {
 | 
			
		|||
				new OAuth2ClientCredentialsGrantRequest(clientRegistration);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(clientCredentialsGrantRequest))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessageContaining("[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getTokenResponseWhenMalformedResponseThenThrowOAuth2AuthenticationException() {
 | 
			
		||||
	public void getTokenResponseWhenMalformedResponseThenThrowOAuth2AuthorizationException() {
 | 
			
		||||
		String accessTokenSuccessResponse = "{\n" +
 | 
			
		||||
				"	\"access_token\": \"access-token-1234\",\n" +
 | 
			
		||||
				"   \"token_type\": \"bearer\",\n" +
 | 
			
		||||
| 
						 | 
				
			
			@ -268,12 +268,12 @@ public class DefaultClientCredentialsTokenResponseClientTests {
 | 
			
		|||
				new OAuth2ClientCredentialsGrantRequest(this.clientRegistration);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(clientCredentialsGrantRequest))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessageContaining("[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getTokenResponseWhenErrorResponseThenThrowOAuth2AuthenticationException() {
 | 
			
		||||
	public void getTokenResponseWhenErrorResponseThenThrowOAuth2AuthorizationException() {
 | 
			
		||||
		String accessTokenErrorResponse = "{\n" +
 | 
			
		||||
				"   \"error\": \"unauthorized_client\"\n" +
 | 
			
		||||
				"}\n";
 | 
			
		||||
| 
						 | 
				
			
			@ -283,19 +283,19 @@ public class DefaultClientCredentialsTokenResponseClientTests {
 | 
			
		|||
				new OAuth2ClientCredentialsGrantRequest(this.clientRegistration);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(clientCredentialsGrantRequest))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessageContaining("[unauthorized_client]");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getTokenResponseWhenServerErrorResponseThenThrowOAuth2AuthenticationException() {
 | 
			
		||||
	public void getTokenResponseWhenServerErrorResponseThenThrowOAuth2AuthorizationException() {
 | 
			
		||||
		this.server.enqueue(new MockResponse().setResponseCode(500));
 | 
			
		||||
 | 
			
		||||
		OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest =
 | 
			
		||||
				new OAuth2ClientCredentialsGrantRequest(this.clientRegistration);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.tokenResponseClient.getTokenResponse(clientCredentialsGrantRequest))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessage("[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 500 Server Error");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ import org.junit.Test;
 | 
			
		|||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.springframework.mock.http.client.MockClientHttpResponse;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ public class OAuth2ErrorResponseErrorHandlerTests {
 | 
			
		|||
				errorResponse.getBytes(), HttpStatus.BAD_REQUEST);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.errorHandler.handleError(response))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessage("[unauthorized_client] The client is not authorized");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ public class OAuth2ErrorResponseErrorHandlerTests {
 | 
			
		|||
		response.getHeaders().add(HttpHeaders.WWW_AUTHENTICATE, wwwAuthenticateHeader);
 | 
			
		||||
 | 
			
		||||
		assertThatThrownBy(() -> this.errorHandler.handleError(response))
 | 
			
		||||
				.isInstanceOf(OAuth2AuthenticationException.class)
 | 
			
		||||
				.isInstanceOf(OAuth2AuthorizationException.class)
 | 
			
		||||
				.hasMessage("[insufficient_scope] The access token expired");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue