Describe the bug
I have a Spring application using spring-security-oauth2-client. It authenticates via OAuth2 using AuthorizedClientServiceOAuth2AuthorizedClientManager.authorize(OAuth2AuthorizeRequest authorizeRequest).
The authorization endpoint is in TIBCO Cloud Mashery. Due to a typo in the URL, the OAuth endpoint failed with Mashery's custom 596 error code. However, rather than return a sensible error in this scenario, the Spring code throws an IllegalArgumentException trying to convert the status code to an HttpStatus:
java.lang.IllegalArgumentException: No matching constant for [596]
at org.springframework.http.HttpStatus.valueOf(HttpStatus.java:538)
at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:33)
at org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler.handleError(OAuth2ErrorResponseErrorHandler.java:51)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:782)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:740)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:641)
at org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient.getTokenResponse(DefaultClientCredentialsTokenResponseClient.java:75)
at org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient.getTokenResponse(DefaultClientCredentialsTokenResponseClient.java:52)
at org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider.authorize(ClientCredentialsOAuth2AuthorizedClientProvider.java:86)
at org.springframework.security.oauth2.client.DelegatingOAuth2AuthorizedClientProvider.authorize(DelegatingOAuth2AuthorizedClientProvider.java:67)
at org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager.authorize(AuthorizedClientServiceOAuth2AuthorizedClientManager.java:140)
This is due to the usage of ClientHttpResponse.getStatusCode() in OAuth2ErrorResponseErrorHandler.java:
https://github.com/spring-projects/spring-security/blob/006b9b960797d279b31cf8c8d16f1549c5632b2c/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandler.java#L55-L57
Replacing getStatusCode with getRawStatusCode should be sufficient to fix this issue, in particular given that DefaultResponseErrorHandler already properly handles unknown status codes.
if (HttpStatus.BAD_REQUEST.value() != response.getRawStatusCode()) {
this.defaultErrorHandler.handleError(response);
}
To Reproduce
Call AuthorizedClientServiceOAuth2AuthorizedClientManager.authorize against an endpoint that returns a nonstandard error HTTP status code (any 4xx or 5xx series response code not defined in HttpStatus). An IllegalArgumentException is thrown with message No matching constant for [596] (replacing 596 with the actual response code).
Expected behavior
This should fail in the exact same way as any other non-400 error response codes, namely calling DefaultResponseErrorHandler.handleError with the ClientHttpResponse.
Comment From: sjohnr
Hi @mjustin - I agree that this seems a relatively easy fix and would not cause problems any longer for custom response codes. Would you be willing to submit a pull request to fix this, with a corresponding test to verify your scenario (596 response code or any other non-standard, e.g. nginx's 499 response code) no longer causes an issue?
Comment From: spring-projects-issues
Fixed via de4b3a4310b99361eee5966b519b7b6ca1e505d7