Expected Behavior
Having ReactiveRemoteJWKSource public
Current Behavior
ReactiveRemoteJWKSource is package only accessible
Context
As it turns up, we are using the nimbus library for validating JWTs and we got the same requirements of having a RemoteJWKSet using Spring reactive. Seems you did all the hard work, it is just not accessible. Would it be possible to make it public?
btw, this is more a NimbusReactiveRemoteJWKSource if we follow your convention named you used for NimbusReactiveJwtDecoder.
Comment From: jzheaux
Hi, @qcastel, thanks for the suggestion.
As it turns up, we are using the nimbus library for validating JWTs and we got the same requirements of having a RemoteJWKSet using Spring reactive.
This sounds like what NimbusReactiveJwtDecoder was built for. For example:
NimbusReactiveJwtDecoder decoder = ReactiveJwtDecoders.fromIssuerLocation(...);
Mono<Jwt> decodeAndValidatedJwt = decoder.decode(encodedJwt); // decode and validate the JWT
What makes NimbusReactiveJwtDecoder unfit for what you are wanting to do?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: qcastel
Hello @jzheaux,
In your above example, you return a org.springframework.security.oauth2.jwt.Jwt, which we are trying to avoid as we are using the Nimbus library too.
This is inconvenient for us to have to convert org.springframework.security.oauth2.jwt.Jwt into com.nimbusds.jwt.JWT, this is why we would prefer consuming directly ReactiveRemoteJWKSource
Thanks!
Comment From: jzheaux
Gotcha, @qcastel. If you are wanting to use Nimbus directly, I think the best source would be to raise an issue with the Nimbus team, since that's where Nimbus APIs should live. If you end up creating an issue, feel free to link it back here so others can continue to track progress.
I don't know if Nimbus already has reactive plans, but perhaps your use case can get the conversation started. Feel free to take anything applicable from ReactiveRemoteJWKSource to suit those needs.
FWIW, if you are in a position to change, some of the nice things about Spring's Jwt are the lack of checked exceptions in the getters, it's type-casting optimizations, and support for Instant, for example:
String subject;
Instant expiresAt;
try {
subject = nimbusJWT.getJWTClaimsSet().getSubject();
Date e = nimbusJWT.getJWTClaimsSet().getExpirationTime();
if (e != null) {
expiresAt = e.toInstant();
}
} catch (ParseException e) {
// handle
}
vs
String subject = springJwt.getSubject();
Instant expiresAt = springJwt.getExpiresAt();
But if not, I think you only need to do the conversion once with a custom JwtAuthenticationConverter:
public class JWTAuthenticationConverter implements Converter<Jwt, JWTAuthentication> {
private final JwtAuthenticationConverter delegate = new JwtAuthenticationConverter();
@Override
public JWTAuthentication convert(Jwt springJwt) {
Authentication authentication = delegate.convert(springJwt);
JWT nimbusJWT = onetimeConversion(springJwt);
return new JWTAuthentication(nimbusJWT, springJwt, authentication.getAuthorities());
}
}
Following this pattern, you can still use NimbusReactiveJwtDecoder and only convert Jwt into JWT once.