-
Notifications
You must be signed in to change notification settings - Fork 6k
Add NimbusJwtDecoder #5936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add NimbusJwtDecoder #5936
Conversation
* A low-level Nimbus implementation of {@link JwtDecoder} which takes a raw Nimbus configuration. | ||
* | ||
* @author Josh Cummings | ||
* @since 5.1.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot be introduced in a patch version. See Semantic Versioning and Apache Versioning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- If we deprecate an API we should do our best to remove the usage within our code base. Can you find usage of
NimbusJwtDecoderJwkSupport
and replace it? NimbusJwtDecoderJwkSupport
was deprecated, but not all the functionality is replaced. For example, there is no easy way for users to leverageRestOperations
withNimbusJwtDecoder
. I think we should add simple builder methods that simplify creating aNimbusJwtDecoder
from a jwkSetUrl and allows setting aRestOperations
for usage.
@rwinch That sounds reasonable. Regarding the builder, there is a separate ticket for providing this capability in a separate class (not directly on NimbusJwtDecoder). Would it be better to add that builder functionality onto NimbusJwtDecoder itself and in this PR? |
@jzheaux Yes. Let's merge with this issue. |
@rwinch I added the builder, which exposes rest operations functionality. This should achieve parity with what |
* @author Josh Cummings | ||
* @since 5.2 | ||
*/ | ||
public static class Builder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's rename this to be more precise. When we add support for building with a static key, we want to ensure that it isn't confusing that support isn't on this builder. Perhaps a name of JwkSetUriBuilder
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit surprising to me that the Builder
only provides the properties to build the JWTProcessor
for the constructor to NimbusJwtDecoder
. After using the Builder
to create NimbusJwtDecoder
, I'm not sure I would think to look for properties on NimbusJwtDecoder
(i.e. setClaimSetConverter
) for additional customization.
I wonder if the Builder
should either
- Have all the properties on it
- Build a
JWTProcessor
instead
Other options are welcome
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of introducing additional properties, and in fact, I would prefer that when constructing these myself. I prefer treating my objects as immutable after using a builder.
I think that building a JWTProcessor
could work, but it also might encourage a very Nimbus-like API. While this is indeed a Nimbus-specific class, I'm not sure I want to position this as an authoritative way to configure Nimbus primitives.
* @param jwkSetUri the JWK Set uri to use | ||
* @return a {@link Builder} for further configurations | ||
*/ | ||
public static Builder withJwkSetUri(String jwkSetUri) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move this method outside of the builder to the class level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add validation on jwkSetUri. At minimum it should ensure that the String is not null or empty.
* @author Joe Grandja | ||
* @author Josh Cummings | ||
* @since 5.0 | ||
* @see JwtDecoder | ||
* @see NimbusJwtDecoder | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7519">JSON Web Token (JWT)</a> | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7515">JSON Web Signature (JWS)</a> | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> | ||
* @see <a target="_blank" href="https://connect2id.com/products/nimbus-jose-jwt">Nimbus JOSE + JWT SDK</a> | ||
*/ | ||
public final class NimbusJwtDecoderJwkSupport implements JwtDecoder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if we have done things well in NimbusJwtDecoder
then we should be able to delete more of this class. For example, I don't think we should need RestOperationsResourceRetriever
. A way to minimize this would be to have a member of the Builder
and a member of the NimbusJwtDecoder
If a setter is invoked, it updates the builder and then builds a new delegate NimbusJwtDecoder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed with @rwinch here as far as member variable for Builder
that builds a new NimbusJwtDecoder
when a setter is invoked. I also think all the code in the constructor should be deleted and simply use the NimbusJwtDecoder.Builder
to build the delegate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also add @Deprecated
at class level
* | ||
* @return the configured {@link JwtDecoder} | ||
*/ | ||
public NimbusJwtDecoder build() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should return JwtDecoder
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, @jgrandja in the latest PR that the builder now returns JWTProcessor
instead.
Though, I was debating the same thing as you at the time.
* | ||
* @param jwtValidator - the Jwt Validator to use | ||
*/ | ||
public final void setJwtValidator(OAuth2TokenValidator<Jwt> jwtValidator) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final
is not really necessary here since the class is marked final
* | ||
* @param claimSetConverter the {@link Converter} to use | ||
*/ | ||
public final void setClaimSetConverter(Converter<Map<String, Object>, Map<String, Object>> claimSetConverter) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final
is not really necessary here since the class is marked final
Map<String, Object> claims = this.claimSetConverter.convert(jwtClaimsSet.getClaims()); | ||
|
||
Instant expiresAt = (Instant) claims.get(JwtClaimNames.EXP); | ||
Instant issuedAt = (Instant) claims.get(JwtClaimNames.IAT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test if issuedAt == null
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @return a {@link Builder} for further configurations | ||
*/ | ||
public Builder jwsAlgorithm(String jwsAlgorithm) { | ||
Assert.notNull(jwsAlgorithm, "jwsAlgorithm cannot be null"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Assert.hasText
return new NimbusJwtDecoder(jwtProcessor); | ||
} | ||
|
||
private static URL toURL(Object url) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the parameter type Object
instead of String?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't remember now. It was needed in an early draft, but it appears I forgot to clean it up.
* @author Joe Grandja | ||
* @author Josh Cummings | ||
* @since 5.0 | ||
* @see JwtDecoder | ||
* @see NimbusJwtDecoder | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7519">JSON Web Token (JWT)</a> | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7515">JSON Web Signature (JWS)</a> | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> | ||
* @see <a target="_blank" href="https://connect2id.com/products/nimbus-jose-jwt">Nimbus JOSE + JWT SDK</a> | ||
*/ | ||
public final class NimbusJwtDecoderJwkSupport implements JwtDecoder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed with @rwinch here as far as member variable for Builder
that builds a new NimbusJwtDecoder
when a setter is invoked. I also think all the code in the constructor should be deleted and simply use the NimbusJwtDecoder.Builder
to build the delegate.
* @author Joe Grandja | ||
* @author Josh Cummings | ||
* @since 5.0 | ||
* @see JwtDecoder | ||
* @see NimbusJwtDecoder | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7519">JSON Web Token (JWT)</a> | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7515">JSON Web Signature (JWS)</a> | ||
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> | ||
* @see <a target="_blank" href="https://connect2id.com/products/nimbus-jose-jwt">Nimbus JOSE + JWT SDK</a> | ||
*/ | ||
public final class NimbusJwtDecoderJwkSupport implements JwtDecoder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also add @Deprecated
at class level
Introduces a JwtDecoder which takes a raw Nimbus JWTProcessor configuration. Fixes: spring-projectsgh-5648
A Builder to simply common construction patterns for NimbusJwtDecoder Issue: spring-projectsgh-6010
Thanks for the PR @jzheaux! This is now merged into master |
Introduces a JwtDecoder which takes a raw Nimbus JWTProcessor
configuration.
Fixes: gh-5648