From 22272321f29adb73ff85a237106a5bafa0d9fb87 Mon Sep 17 00:00:00 2001 From: Steve Riesenberg Date: Tue, 18 May 2021 14:00:56 -0500 Subject: [PATCH] Handle custom status codes in error handler Fixes an issue where custom status codes in the error response cause an IllegalArgumentException to be thrown when resolving an HttpStatus. Closes gh-9741 --- .../http/OAuth2ErrorResponseErrorHandler.java | 2 +- .../OAuth2ErrorResponseErrorHandlerTests.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandler.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandler.java index 3f865a5897..fb74797e80 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandler.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandler.java @@ -48,7 +48,7 @@ public class OAuth2ErrorResponseErrorHandler implements ResponseErrorHandler { @Override public void handleError(ClientHttpResponse response) throws IOException { - if (!HttpStatus.BAD_REQUEST.equals(response.getStatusCode())) { + if (HttpStatus.BAD_REQUEST.value() != response.getRawStatusCode()) { this.defaultErrorHandler.handleError(response); } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandlerTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandlerTests.java index 98e2b72bb2..731d16cdd9 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandlerTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorResponseErrorHandlerTests.java @@ -15,12 +15,19 @@ */ package org.springframework.security.oauth2.client.http; +import java.io.IOException; + import org.junit.Test; + import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.mock.http.MockHttpInputMessage; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.security.oauth2.core.OAuth2AuthorizationException; +import org.springframework.web.client.UnknownHttpStatusCodeException; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** @@ -58,4 +65,49 @@ public class OAuth2ErrorResponseErrorHandlerTests { .isInstanceOf(OAuth2AuthorizationException.class) .hasMessage("[insufficient_scope] The access token expired"); } + + @Test + public void handleErrorWhenErrorResponseWithInvalidStatusCodeThenHandled() { + CustomMockClientHttpResponse response = new CustomMockClientHttpResponse(new byte[0], 596); + assertThatExceptionOfType(UnknownHttpStatusCodeException.class) + .isThrownBy(() -> this.errorHandler.handleError(response)).withMessage("596 : [no body]"); + } + + private static final class CustomMockClientHttpResponse extends MockHttpInputMessage implements ClientHttpResponse { + + private final int statusCode; + + private CustomMockClientHttpResponse(byte[] content, int statusCode) { + super(content); + this.statusCode = statusCode; + } + + @Override + public HttpStatus getStatusCode() throws IOException { + return HttpStatus.valueOf(getRawStatusCode()); + } + + @Override + public int getRawStatusCode() { + return this.statusCode; + } + + @Override + public String getStatusText() throws IOException { + HttpStatus httpStatus = HttpStatus.resolve(this.statusCode); + return (httpStatus != null) ? httpStatus.getReasonPhrase() : ""; + } + + @Override + public void close() { + try { + getBody().close(); + } + catch (IOException ex) { + // ignore + } + } + + } + }