spring-projects / spring-projects/spring-security

Customizable set of JwtClaimValidators for OAuth Resource Server

Open
#13,249 7 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: config type: enhancement
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Expected Behavior

I expect that additional JwtClaimValidator instances should be easily configured and injected for token processing. It should not require disabling auto-configuration logic that is very helpful in many aspects. Possible solution is to use declared beans of JwtClaimValidator type.

Current Behavior

Currently there is no way to add custom validators without redefining the whole OAuth2ResourceServerJwtConfiguration because validators are not injected but created inside the configuration.

Context

I'm implementing a starter library for microservices system. I created my own auto configuration class and it's quite small because I mostly rely on the OAuth2ResourceServerJwtConfiguration. But when I need to add a custom JWT claims validator the only way to do it is to redefine the whole standard configuration. It's not convenient because the standard configuration contains must have validators like issuer validator and some other logic that is useful (e.g. resolving the source of public key for token validation). I think there is much more room for errors in this approach then if we just provide a way to add custom validators without touching the default configuration.

What I have now is just the same configuration class as in the Spring Security library but I inject all the beans of JwtClaimValidator type to the field and then add all those beans to the list of validators

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(JwtDecoder.class)
static class JwtDecoderConfiguration {

    private final OAuth2ResourceServerProperties properties;
    private final List<JwtClaimValidator<?>> claimValidators;

    JwtDecoderConfiguration(OAuth2ResourceServerProperties properties, List<JwtClaimValidator<?>> claimValidators) {
      this.properties = properties;
      this.claimValidators = claimValidators;
    }

    private OAuth2TokenValidator<Jwt> getValidators(Supplier<OAuth2TokenValidator<Jwt>> defaultValidator) {
      OAuth2TokenValidator<Jwt> defaultValidators = defaultValidator.get();
      List<String> audiences = this.properties.getAudiences();
      List<OAuth2TokenValidator<Jwt>> validators = new ArrayList<>();
      validators.add(defaultValidators);
      validators.addAll(claimValidators);
      if (!CollectionUtils.isEmpty(audiences)) {
        validators.add(new JwtClaimValidator<List<String>>(JwtClaimNames.AUD,
          (aud) -> aud != null && !Collections.disjoint(aud, audiences)));
      }
      return new DelegatingOAuth2TokenValidator<>(validators);
    }
   
    // All code from OAuth2ResourceServerJwtConfiguration
    ...
  }

It is a working solution but in my opinion it'd be much more convenient and less error prone if it worked this way out of the box.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading OAuth2ResourceServerJwtConfiguration and tracing how JwtClaimValidator instances are created and composed with the default issuer and audience validation. Done means custom validators can be supplied without redefining the full configuration, while the existing default validation and public-key resolution behavior remain intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
authentication, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.