Expected Behavior
OidcIdTokenDecoderFactory should provide a setter method to configure "jwtProcessorCustomizer" for applying it on NimbusJwtDecoder instances.
This allow application to configure JWE Key Selector via the customizer, and enabling id token decryption, which already supported by NimbusJwtDecoder / DefaultJWTProcessor.
Current Behavior
When integrating with an authorization server that does return encrypted id_token using JWE, Spring OAuth Login is failed for processing id_token, due to missing "jweKeySelector" in DefaultJWTProcessor.
Context
Without the suppose changes on OidcIdTokenDecoderFactory, I end up need to rewrite OidcIdTokenDecoderFactory.
Comment From: ufkl
The following are the proposed on OidcIdTokenDecoderFactory.
public class OidcIdTokenDecoderFactory implements JwtDecoderFactory<ClientRegistration> {
...
private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer = (processor) -> {
};
/**
* Generate {@link JwtDecoder} based on client registration.
*
* @param clientRegistration client registration
* @return new JwtDecoder
*/
private NimbusJwtDecoder buildDecoder(ClientRegistration clientRegistration) {
JwsAlgorithm jwsAlgorithm = this.jwsAlgorithmResolver.apply(clientRegistration);
if (jwsAlgorithm != null && SignatureAlgorithm.class.isAssignableFrom(jwsAlgorithm.getClass())) {
...
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
.jwsAlgorithm((SignatureAlgorithm) jwsAlgorithm)
.jwtProcessorCustomizer(this.jwtProcessorCustomizer)
.build();
}
if (jwsAlgorithm != null && MacAlgorithm.class.isAssignableFrom(jwsAlgorithm.getClass())) {
..
return NimbusJwtDecoder.withSecretKey(secretKeySpec)
.macAlgorithm((MacAlgorithm) jwsAlgorithm)
.jwtProcessorCustomizer(this.jwtProcessorCustomizer)
.build();
}
...
}
/**
* Customise JWT Processor, e.g. JWT decryption.
*
* @param jwtProcessorCustomizer customizer
*/
public void setJwtProcessorCustomizer(Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer) {
this.jwtProcessorCustomizer = jwtProcessorCustomizer;
}
}
Comment From: jzheaux
@ufkl thanks for the suggestion. Given that the other methods are multi-tenant, I think that setJwtProcessorCustomizer should instead be setJwtProcessorCustomizerFactory.
Are you able to submit a PR adding the method?
Comment From: ufkl
Sure. Let me look at contributing guidelines first I submit PR.
Comment From: jgrandja
@ufkl @jzheaux I don't think we should add setJwtProcessorCustomizer(Consumer<ConfigurableJWTProcessor<SecurityContext>>.
The main reason is that we only expose Nimbus API's in a Nimbus implementation, which has the Nimbus prefix in class name, e.g. NimbusJwtDecoder, NimbusJwtClientAuthenticationParametersConverter, NimbusOpaqueTokenIntrospector, etc.
Even though OidcIdTokenDecoderFactory uses Nimbus internally, no Nimbus API's are exposed at the moment so we technically can change the internal implementation if needed.
Without the suppose changes on
OidcIdTokenDecoderFactory, I end up need to rewriteOidcIdTokenDecoderFactory
Most of the components used in OidcIdTokenDecoderFactory can be reused in a custom implementation of JwtDecoderFactory<ClientRegistration>. Please see this comment.
Comment From: jzheaux
The main reason is that we only expose Nimbus API's in a Nimbus implementation
Good catch, @jgrandja. We don't want to reference Nimbus in a non-Nimbus public API.