Issue#1050 is closed by adding support to handle multiple JWK set URLs. But there is not way by which we can set these MULTIPLe url in properties files.
i.e. security.oauth2.resource.jwk.key-set-uri property takes single value. We can not specify comma separated jwk set urls.
Last comment by @jgrandja say the same thing "file a separate issue to handle multiple JWK set urls through property"
IMO possible fix is,
In ResourceServerProperties#
`public class Jwk {
private String[] keySetUri;
public String getKeySetUri() {
return this.keySetUri;
}
public void setKeySetUri(String keySetUri) {
this.keySetUri = keySetUri.split(",");
}
}`
Any update on this? Would love to see this feature.
would also very much like to see this feature implemented
@DomhnallP I ended up having to rig up my own implementation using TokenServices. I'm happy to share.
@annagapuz can you please share?
My company is in the process of migrating from one authorization server to another, so the ability to support multiple JWK set URIs through properties would be enormously helpful. @jgrandja any traction on this issue?
@pnewhook Please see the recent announcement
Thanks @jgrandja I didn't realize this issue was in the old library. But isn't this still an outstanding feature request for Spring Security 5?
@annagapuz can you please share?
I had to write my own implementation of ResourceServerTokenServices that initialized a JwkTokenStore. A JwkTokenStore can take a list of JWKS URLs. Although, I believe this class is deprecated with the latest Spring Security, so I'll have to figure something else out.
public class MyTokenServices implements ResourceServerTokenServices {
private TokenStore tokenStore;
@PostConstruct
private void init() {
tokenStore = new JwkTokenStore(listOfJwksUrls);
}
@Override
public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, InvalidTokenException {
// ...
OAuth2AccessToken accessToken = tokenStore.readAccessToken(accessTokenValue);
}
}
@Bean
public TokenServices tokenServices() {
return new MyTokenServices();
}
@Configuration
@EnableResourceServer
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyWebSecurityConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private TokenServices tokenServices;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.tokenServices(tokenServices);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic().disable()
.formLogin().disable()
.authorizeRequests()
.anyRequest().authenticated();
}
}
Curious to know if anyone has done the upgrade and has found a way to do multiple JWKS URLs? I was using DSL before but the need for multiple URLs plus the parsing of custom tokens led me down a different path.
@jgrandja
Is creating a custom JwtDecoder that contains multiple NimbusJwtDecoder instances be the expected strategy for handling multiple JWKS URLs?
We have a similar problem in my current project.
We use Okta for authz, but want to sign our own JWTs for service to service communication.
I'm thinking of solving this by aggregating the Okta JWKs with our own JWKs into an endpoint hosted internally.
Then in our services, we use this internal uri for security.oauth2.resource.jwk.key-set-uri
Thoughts?
Update - This worked perfectly.
I modified ReactiveJWKSourceAdapter and NimbusReactiveJwtDecoder to accept one or more RSAKey, in addition to the jwk-set-uri.
Then in our SecurityWebFilterChain, I use this new decoder implementation.
To allow our microservices to validate tokens either signed by our auth server or Okta, we host a rest endpoint serving the aggregated list of JWKs.
Worked like a charm!
@jdbranham Can u share the code ?
Sure @senthilsivanath -
I created a library just now.
https://github.com/savantly-net/spring-multi-jwk-source
It would be great to collaborate with someone on this. I built it for a specific use-case, but it could be modified to be a more general solution.