Allow custom OAuth2ErrorHttpMessageConverter with OAuth2ErrorResponseErrorHandler
Closes gh-10425
This commit is contained in:
parent
96a6fef820
commit
00fafd878c
|
@ -23,10 +23,12 @@ import com.nimbusds.oauth2.sdk.token.BearerTokenError;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.client.ClientHttpResponse;
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
|
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
|
||||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||||
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
|
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
|
||||||
import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMessageConverter;
|
import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMessageConverter;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.client.DefaultResponseErrorHandler;
|
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||||
import org.springframework.web.client.ResponseErrorHandler;
|
import org.springframework.web.client.ResponseErrorHandler;
|
||||||
|
@ -41,7 +43,7 @@ import org.springframework.web.client.ResponseErrorHandler;
|
||||||
*/
|
*/
|
||||||
public class OAuth2ErrorResponseErrorHandler implements ResponseErrorHandler {
|
public class OAuth2ErrorResponseErrorHandler implements ResponseErrorHandler {
|
||||||
|
|
||||||
private final OAuth2ErrorHttpMessageConverter oauth2ErrorConverter = new OAuth2ErrorHttpMessageConverter();
|
private HttpMessageConverter<OAuth2Error> oauth2ErrorConverter = new OAuth2ErrorHttpMessageConverter();
|
||||||
|
|
||||||
private final ResponseErrorHandler defaultErrorHandler = new DefaultResponseErrorHandler();
|
private final ResponseErrorHandler defaultErrorHandler = new DefaultResponseErrorHandler();
|
||||||
|
|
||||||
|
@ -89,4 +91,15 @@ public class OAuth2ErrorResponseErrorHandler implements ResponseErrorHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link HttpMessageConverter} for an OAuth 2.0 Error.
|
||||||
|
* @param oauth2ErrorConverter A {@link HttpMessageConverter} for an
|
||||||
|
* {@link OAuth2Error OAuth 2.0 Error}.
|
||||||
|
* @since 5.7
|
||||||
|
*/
|
||||||
|
public final void setErrorConverter(HttpMessageConverter<OAuth2Error> oauth2ErrorConverter) {
|
||||||
|
Assert.notNull(oauth2ErrorConverter, "oauth2ErrorConverter cannot be null");
|
||||||
|
this.oauth2ErrorConverter = oauth2ErrorConverter;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,19 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.client.ClientHttpResponse;
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.mock.http.MockHttpInputMessage;
|
import org.springframework.mock.http.MockHttpInputMessage;
|
||||||
import org.springframework.mock.http.client.MockClientHttpResponse;
|
import org.springframework.mock.http.client.MockClientHttpResponse;
|
||||||
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
|
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
|
||||||
|
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||||
import org.springframework.web.client.UnknownHttpStatusCodeException;
|
import org.springframework.web.client.UnknownHttpStatusCodeException;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link OAuth2ErrorResponseErrorHandler}.
|
* Tests for {@link OAuth2ErrorResponseErrorHandler}.
|
||||||
|
@ -53,6 +60,26 @@ public class OAuth2ErrorResponseErrorHandlerTests {
|
||||||
.withMessage("[unauthorized_client] The client is not authorized");
|
.withMessage("[unauthorized_client] The client is not authorized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleErrorWhenOAuth2ErrorConverterSetThenCalled() throws IOException {
|
||||||
|
HttpMessageConverter<OAuth2Error> oauth2ErrorConverter = mock(HttpMessageConverter.class);
|
||||||
|
this.errorHandler.setErrorConverter(oauth2ErrorConverter);
|
||||||
|
// @formatter:off
|
||||||
|
String errorResponse = "{\n"
|
||||||
|
+ " \"errorCode\": \"unauthorized_client\",\n"
|
||||||
|
+ " \"errorSummary\": \"The client is not authorized\"\n"
|
||||||
|
+ "}\n";
|
||||||
|
// @formatter:on
|
||||||
|
MockClientHttpResponse response = new MockClientHttpResponse(errorResponse.getBytes(), HttpStatus.BAD_REQUEST);
|
||||||
|
given(oauth2ErrorConverter.read(any(), any()))
|
||||||
|
.willReturn(new OAuth2Error("unauthorized_client", "The client is not authorized", null));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(OAuth2AuthorizationException.class)
|
||||||
|
.isThrownBy(() -> this.errorHandler.handleError(response))
|
||||||
|
.withMessage("[unauthorized_client] The client is not authorized");
|
||||||
|
verify(oauth2ErrorConverter).read(eq(OAuth2Error.class), eq(response));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleErrorWhenErrorResponseWwwAuthenticateHeaderThenHandled() {
|
public void handleErrorWhenErrorResponseWwwAuthenticateHeaderThenHandled() {
|
||||||
String wwwAuthenticateHeader = "Bearer realm=\"auth-realm\" error=\"insufficient_scope\" error_description=\"The access token expired\"";
|
String wwwAuthenticateHeader = "Bearer realm=\"auth-realm\" error=\"insufficient_scope\" error_description=\"The access token expired\"";
|
||||||
|
|
Loading…
Reference in New Issue