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