Skip to content

Allow customization of error and HTTP response within OAuth2AuthenticationFailureHandler #1465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

ddubson
Copy link
Contributor

@ddubson ddubson commented Nov 28, 2023

This is an initial proof-of-concept for the last segment of gh-1369, as stated in the original:

For the second iteration, let's see if we can come up with a hook in the new AuthenticationFailureHandler that will allow for reuse and customization for these additional Filter's:

OAuth2ClientAuthenticationFilter
OidcUserInfoEndpointFilter
OidcClientRegistrationEndpointFilter

There are currently failing existing test cases, and no additional new test cases, as this draft PR is meant for early review of the approach.

Once the rough sketch is approved for this implementation, the TODO list is as follows:

  • Fix failing existing test cases
  • Add test coverage for the newly implemented functionality
  • Polish and document newly added functions or blocks

Fixes gh-1369

@ddubson
Copy link
Contributor Author

ddubson commented Nov 28, 2023

@jgrandja -- I'd like to get your input as to the approach for this implementation, let me know if you need further clarification on any part of this draft.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 28, 2023
Copy link
Collaborator

@jgrandja jgrandja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @ddubson. Please see review comments.

@@ -47,14 +49,18 @@ public final class OAuth2ErrorAuthenticationFailureHandler implements Authentica
private final Log logger = LogFactory.getLog(getClass());
private HttpMessageConverter<OAuth2Error> errorResponseConverter = new OAuth2ErrorHttpMessageConverter();

private BiConsumer<OAuth2AuthenticationException, ServletServerHttpResponse> httpResponseCustomizer = (exception, httpResponse) -> httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how I feel about using a BiConsumer. Currently, the framework does not make use of BiConsumer. I'll have to think about this for a bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will a Context class work in this situation? Now that I've learned about that pattern, I can see it fitting in here, however I'm not sure if the project uses it in handling error conditions as this warrants.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense to use a context class here.

I've been giving this some more thought and I'm starting to wonder if any changes are needed after all.

We have the ability to customize the error response parameters as mentioned in this comment, so the only other customization required at this point is to change the status code. However, this can be done using this:

private AuthenticationFailureHandler authenticationFailureHandler = createAuthenticationFailureHandler();

private static AuthenticationFailureHandler createAuthenticationFailureHandler() {
	OAuth2ErrorHttpMessageConverter errorResponseConverter = new OAuth2ErrorHttpMessageConverter() {
		@Override
		protected void writeInternal(OAuth2Error error, HttpOutputMessage outputMessage)
				throws HttpMessageNotWritableException {

			HttpServletResponse servletResponse = ((ServletServerHttpResponse) outputMessage).getServletResponse();
			if (OAuth2ErrorCodes.INVALID_CLIENT.equals(error.getErrorCode())) {
				servletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
			} else {
				servletResponse.setStatus(HttpStatus.BAD_REQUEST.value());
			}
			super.writeInternal(error, outputMessage);
		}

	};
	errorResponseConverter.setErrorParametersConverter(error -> {
		Map<String, String> parameters = new HashMap<>();
		parameters.put(OAuth2ParameterNames.ERROR, error.getErrorCode());
		return parameters;

	});

	OAuth2ErrorAuthenticationFailureHandler authenticationFailureHandler = new OAuth2ErrorAuthenticationFailureHandler();
	authenticationFailureHandler.setErrorResponseConverter(errorResponseConverter);

	return authenticationFailureHandler;
}

This AuthenticationFailureHandler would work for OAuth2ClientAuthenticationFilter. I know it's not pretty though.

I'm just having 2nd thoughts on introducing a new API just so we can customize the status code. Furthermore, no one from the community has asked for this specific customization. I realize this is my ask in the hopes of reusing OAuth2ErrorAuthenticationFailureHandler for the other 3x Filter's.

What are your thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's little to no demand from the developer/consumer side, I think a good course of action is to document the approach you mentioned above as a way to do the error customization somewhere within the official docs -- that may very well be useful to those that need it in the future, without spending time and effort for an API change.

Additionally, a test case demonstrating this customization approach could also be useful in tandem with the docs change.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a good course of action is to document the approach you mentioned above as a way to do the error customization somewhere within the official docs -- that may very well be useful to those that need it in the future, without spending time and effort for an API change.

Fully agree and good idea on adding the sample customization to the reference. For now, I added the sample code to gh-541 as it should be added as part of that How-to guide.

I'm going to close this PR as we'll hold off on any API changes at this point. Thank you for spending your time on coming up with the right approach 👍

@jgrandja jgrandja self-assigned this Dec 8, 2023
@jgrandja jgrandja added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 8, 2023
@jgrandja jgrandja closed this Jan 30, 2024
@jgrandja jgrandja added status: declined A suggestion or change that we don't feel we should currently apply and removed type: enhancement A general enhancement labels Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow extension and/or modification of success/error response handlers within Filters
3 participants