Browse Source

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
Steve Riesenberg 4 năm trước cách đây
mục cha
commit
d3a3c36ad3

+ 1 - 1
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);
 		}
 

+ 52 - 0
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
+			}
+		}
+
+	}
+
 }