spring-projects / spring-projects/spring-security

NimbusJwtDecoderJwkSupport should offer method to get OAuth2TokenValidator

Open
#6,909 9 comments 5 reactions 1 assignee View on GitHub

@jzheaux is already working on this.

Since Jun 17, 2024.

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

Description

Summary

NimbusJwtDecoderJwkSupport is the underlying implementation for Spring Security JwtDecoder.

NimbusJwtDecoderJwkSupport provides a method to setJwtValidator(OAuth2TokenValidator<Jwt>), but it does not have a method to retrieve the set validator(s).

NimbusJwtDecoderJwkSupport is used to auto-configure a JwtDecoder bean in OAuth2ResourceServerJwkConfiguration and its instantiation and especially the set JWT validators depend on the existence of either a JWKS URI or an Issuer URI from the spring.security.oauth2.resourceserver.jwt.issuer-uri.

If an application or library wants to add additional JWT validators, today's guidance in Spring Security documentation is to re-declare a JwtDecoder bean and set the validators on it.

Problem is, that now the application / library has no access to the configured defaults of Spring Security which (as described above) depend on the user's configurations.

Ideally we would like to do something like this:

public class WebSecurityConfigurations extends WebSecurityConfigurerAdapter {
     WebSecurityConfigurations(JwtDecoder standardSpringSecurityJwtDecoder) {
         NimbusJwtDecoderJwkSupport decoder = ((NimbusJwtDecoderJwkSupport) standardSpringSecurityJwtDecoder);
         OAuth2TokenValidator<Jwt> standardValidators = decoder.getValidator(); // does not work today.
         OAuth2TokenValidator<Jwt> myCustomValidor = new MyCustomValidator();
         OAuth2TokenValidator<Jwt> jwtValidators = new DelegatingOAuth2TokenValidator<Jwt>(standardValidators, myCustomValidator);
         decoder.setJwtValidator(jwtValidators);
    }
...
}

As an alternative, it might also be ok to add an addValidator(OAuth2TokenValidator<Jwt>) method to NimbusJwtDecoderJwkSupport, though presumably it's implementation would result in a lot of chained DelegatingOAuth2TokenValidator<Jwt>s.

Actual Behavior

No way for an application to get the OAuth2TokenValidators of the auto-configured standard Spring Security JwtDecoder.

Expected Behavior

A way for an application to get the OAuth2TokenValidators of the auto-configured standard Spring Security JwtDecoder or to add additional custom OAuth2TokenValidator.

References

OAuth2ResourceServerJwkConfiguration (Auto-Configuration):

/*
 * Copyright 2012-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.oauth2.resource.IssuerUriCondition;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoderJwkSupport;

/**
 * Configures a {@link JwtDecoder} when a JWK Set URI or OpenID Connect Issuer URI is
 * available.
 *
 * @author Madhura Bhave
 * @author Artsiom Yudovin
 */
@Configuration
class OAuth2ResourceServerJwkConfiguration {

	private final OAuth2ResourceServerProperties properties;

	OAuth2ResourceServerJwkConfiguration(OAuth2ResourceServerProperties properties) {
		this.properties = properties;
	}

	@Bean
	@ConditionalOnProperty(name = "spring.security.oauth2.resourceserver.jwt.jwk-set-uri")
	@ConditionalOnMissingBean
	public JwtDecoder jwtDecoderByJwkKeySetUri() {
		return new NimbusJwtDecoderJwkSupport(this.properties.getJwt().getJwkSetUri());
	}

	@Bean
	@Conditional(IssuerUriCondition.class)
	@ConditionalOnMissingBean
	public JwtDecoder jwtDecoderByIssuerUri() {
		return JwtDecoders
				.fromOidcIssuerLocation(this.properties.getJwt().getIssuerUri());
	}

}
Version

Spring Security Version 5.1.5.RELEASE

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.