Skip to content
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

Simplify adding an authentication validator #1003

Open
dlehammer opened this issue Dec 13, 2022 · 5 comments
Open

Simplify adding an authentication validator #1003

dlehammer opened this issue Dec 13, 2022 · 5 comments
Labels
type: enhancement A general enhancement

Comments

@dlehammer
Copy link

Hi spring-authorization-server gurus,

I'm probably holding it wrong, but here goes :)

Expected Behavior

Appending additional validation supplementing the default validation should be a 1st class citizen, preferably via the composite pattern or similar abstraction.
I suggest that appending custom validation should be as easy as invoking a add-method during configuration.

Current Behavior

The documentation outlines a way to override some default validation, while simultaneously being rather verbose.

SNIP..

private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
	return (authenticationProviders) ->
		authenticationProviders.forEach((authenticationProvider) -> {
			if (authenticationProvider instanceof OAuth2AuthorizationCodeRequestAuthenticationProvider) {
				Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
					// Override default redirect_uri validator
					new CustomRedirectUriValidator()
						// Reuse default scope validator
						.andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);

				((OAuth2AuthorizationCodeRequestAuthenticationProvider) authenticationProvider)
					.setAuthenticationValidator(authenticationValidator);
			}
		});
}

SNIP..

While the current support as outlined in the documentation is cumbersome and maintainer unfriendly, it's sufficient for overriding some default validation, it's also brittle as the overrider must explicit maintain the validation chain ( ...andThen(.. ) going forward.

Context

How has this issue affected you?

In-order to append custom validation, I've accumulated an undesired responsibility for maintaining a mirror of the default validation-chain.

What are you trying to accomplish?

Append custom validation, while preserving the default validation as-is.

What other alternatives have you considered?

The OAuth2AuthorizationEndpointConfigurer.addAuthorizationCodeRequestAuthenticationValidator(..), unfortunately it's unreachable outside the package and prepends the validator.

Are you aware of any workarounds?

Unfortunately no :/

@dlehammer dlehammer added the type: enhancement A general enhancement label Dec 13, 2022
@jgrandja
Copy link
Collaborator

@dlehammer

Appending additional validation supplementing the default validation should be a 1st class citizen

We don't want to expose OAuth2AuthorizationEndpointConfigurer.addAuthenticationValidator() at this point for the following reasons:

  1. Not all AuthenticationProvider's have an associated "authentication validator".
  2. OAuth2AuthorizationEndpointConfigurer initializes 2x AuthenticationProvider's and OAuth2TokenEndpointConfigurer initializes 3x AuthenticationProvider's, so we would need a generic API that would allow setting (or adding) an authentication validator to a specific AuthenticationProvider.
  3. Some AuthenticationProvider's have additional setters for overriding behaviour, for example, OAuth2AuthorizationCodeRequestAuthenticationProvider.setAuthorizationCodeGenerator() and it doesn't make sense to expose this in OAuth2AuthorizationEndpointConfigurer since this specific configuration is an implementation detail and not a generic API that can be applied across the various OAuth2*EndpointConfigurer's.

The documentation outlines a way to override some default validation, while simultaneously being rather verbose.

I wouldn't qualify it as verbose as configureAuthenticationValidator() is a minimal custom configuration IMO.

it's also brittle as the overrider must explicit maintain the validation chain ( ...andThen(.. ) going forward.

andThen() is only necessary is you want to preserve the defaults, however, some applications may want to completely override the defaults and therefore andThen() would not be required. The flexibility is there and it's really up to the application requirements.

FYI, the general API OAuth2*EndpointConfigurer.authenticationProviders() provides the flexibility to customize any AuthenticationProvider that is initialized by an OAuth2*EndpointConfigurer. I understand you would prefer a finer grained API but I'm not sure how we would address that from a design standpoint given the reasons as explained above.

For now, I'll leave this issue open and we may address this at a later point.

@jgrandja jgrandja changed the title Appending custom Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator Simplify adding an authentication validator Dec 15, 2022
@jgrandja jgrandja added the status: on-hold We can't start working on this issue yet label Dec 15, 2022
@dlehammer
Copy link
Author

Hi @jgrandja,

Thanks for taking the time to reply.

Perhaps an initial compromise could be access to the default validation chain currently defined by OAuth2AuthorizationCodeRequestAuthenticationValidator#authenticationValidator.

So appending instead would look something like

OAuth2AuthorizationCodeRequestAuthenticationValidator
    .authenticationValidator
        .andThen(new MyAdditionalValidator());

That way it would be possible to utilize the default validation as-is while it evolves over time, eliminating the need for users of additional validation to manually attempt to remember to check/determine if a new version of the spring-authorization-server warrants the need for changes in a particular code-base 🤓

@jgrandja
Copy link
Collaborator

@dlehammer I'm not sure I want to expose OAuth2AuthorizationCodeRequestAuthenticationValidator.authenticationValidator but I like the idea of containing the enhancement to this class to help users customize the authentication validator while preserving the defaults.

I think a static factory method could work, where the provided validator(s) are simply appended to the defaults.

Would you be interested in submitting a PR for this?

@dlehammer
Copy link
Author

Hi @jgrandja,

Thanks for taking the time to reply.

Regarding

Would you be interested in submitting a PR for this?

I've thought about it, and the only thing preventing me is that I'm unsure what would be an acceptable approach.
So if it's still relevant I would be grateful if you could point me towards an "static factory method" spring code example.

Also i noticed #884 that seems like a closely related issue :)

@jgrandja
Copy link
Collaborator

@dlehammer We just released 1.1 and will soon be planning 1.2, which could potentially include this enhancement. Please give me a couple of weeks until we finalize our 1.2 plan and we can go from there. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
Status: Planning
Development

No branches or pull requests

2 participants