Search code examples
spring-bootspring-securityoauth-2.0spring-security-oauth2

How do I add audience validation using Spring OAuth without needing the issuer?


I currently have the following...

@Configuration
@Slf4j
public class AuthConfig {
    @Value("${auth0.audience}")
    private String audience;

    @Getter
    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuer;

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

    @Bean
    public SecurityFilterChain filterChain(
            HttpSecurity http
    ) throws Exception {
        ....
    }

    @Bean
    JwtDecoder jwtDecoder() {
        NimbusJwtDecoder jwtDecoder = JwtDecoders.fromOidcIssuerLocation(issuer);

        OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(audience);
        OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
        OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);

        jwtDecoder.setJwtValidator(withAudience);

        return jwtDecoder;
    }

    private static class AudienceValidator implements OAuth2TokenValidator<Jwt> {
        private final String audience;

        public AudienceValidator(String audience) {
            this.audience = audience;
        }

        public OAuth2TokenValidatorResult validate(Jwt jwt) {
            OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null);

            if (jwt.getAudience().contains(audience)) {
                return OAuth2TokenValidatorResult.success();
            }
            return OAuth2TokenValidatorResult.failure(error);
        }
    }
}

The problem I have with this is that it is my understanding having

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://jackiergleason.auth0.com/

Will create the JwtDecoder bean automagically and I shouldn't need to grab the issuer from the spring property (I would like to just use @ConfigurationProperties and non-spring properties like audience).

So is there a way I can just add the AudienceValidator to the JwtDecode bean created by Spring Security? Or is there something more basic I am doing incorrectly?


Solution

  • I believe you're looking for the audiences setting. Docs here

    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              issuer-uri: https://jackiergleason.auth0.com/
              audiences:
                - my-custom-audience
                - my-second-custom-audience    
    

    With this, requests without audience, or non-matching audience, will result in 401.