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