Skip to content
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

Merged
merged 2 commits into from Nov 14, 2018
Merged

Add NimbusJwtDecoder #5936

merged 2 commits into from Nov 14, 2018

Conversation

jzheaux
Copy link
Contributor

@jzheaux jzheaux commented Oct 10, 2018

Introduces a JwtDecoder which takes a raw Nimbus JWTProcessor
configuration.

Fixes: gh-5648

@jzheaux jzheaux added status: duplicate A duplicate of another issue type: enhancement A general enhancement in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) labels Oct 10, 2018
* A low-level Nimbus implementation of {@link JwtDecoder} which takes a raw Nimbus configuration.
*
* @author Josh Cummings
* @since 5.1.1
Copy link
Contributor

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

@jzheaux jzheaux requested a review from rwinch October 30, 2018 18:50
@rwinch rwinch added this to rwinch in Security Team Oct 31, 2018
@rwinch rwinch moved this from rwinch to In Progress in Security Team Oct 31, 2018
Copy link
Member

@rwinch rwinch left a 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 leverage RestOperations with NimbusJwtDecoder. I think we should add simple builder methods that simplify creating a NimbusJwtDecoder from a jwkSetUrl and allows setting a RestOperations for usage.

@jzheaux
Copy link
Contributor Author

jzheaux commented Oct 31, 2018

@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?

@rwinch
Copy link
Member

rwinch commented Nov 2, 2018

@jzheaux Yes. Let's merge with this issue.

@jzheaux
Copy link
Contributor Author

jzheaux commented Nov 5, 2018

@rwinch I added the builder, which exposes rest operations functionality.

This should achieve parity with what NimbusJwtDecoderJwkSupport was providing.

* @author Josh Cummings
* @since 5.2
*/
public static class Builder {
Copy link
Member

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?

Copy link
Member

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

Copy link
Contributor Author

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) {
Copy link
Member

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.

Copy link
Member

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 {
Copy link
Member

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

Copy link
Contributor

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.

Copy link
Contributor

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() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return JwtDecoder?

Copy link
Contributor Author

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) {
Copy link
Contributor

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) {
Copy link
Contributor

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);
Copy link
Contributor

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?

Copy link
Contributor Author

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");
Copy link
Contributor

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) {
Copy link
Contributor

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?

Copy link
Contributor Author

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 {
Copy link
Contributor

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 {
Copy link
Contributor

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
@jzheaux
Copy link
Contributor Author

jzheaux commented Nov 12, 2018

@rwinch, @jgrandja Thank you both for the valuable feedback. I've updated based on it.

A Builder to simply common construction patterns for NimbusJwtDecoder

Issue: spring-projectsgh-6010
@jzheaux jzheaux moved this from In Progress to jzheaux in Security Team Nov 12, 2018
@jzheaux jzheaux moved this from jzheaux to In Progress in Security Team Nov 12, 2018
@rwinch rwinch changed the title Low-level Nimbus Jwt Decoder Add NimbusJwtDecoder Nov 14, 2018
@rwinch rwinch added this to the 5.2.0.M1 milestone Nov 14, 2018
@rwinch rwinch self-assigned this Nov 14, 2018
@rwinch rwinch merged commit d28e32b into spring-projects:master Nov 14, 2018
@rwinch
Copy link
Member

rwinch commented Nov 14, 2018

Thanks for the PR @jzheaux! This is now merged into master

@jzheaux jzheaux removed this from In Progress in Security Team Nov 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nimbus Jwt Decoder Configurability
3 participants