浏览代码

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 年之前
父节点
当前提交
22272321f2

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