Skip to content

Make X509CertificateThumbprintValidator configurable through JwtValidators create APIs #17131

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

Closed
edmundham opened this issue May 17, 2025 · 3 comments
Assignees
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

Comments

@edmundham
Copy link

Expected Behavior

X509CertificateThumbprintValidator should be public and without final OR it should expose some way to set custom Supplier<X509Certificate>

Current Behavior
Currently, X509CertificateThumbprintValidator is built with the DefaultX509CertificateSupplier. This is not configurable because:

  1. X509CertificateThumbprintValidator is a default visibility with final class
  2. JwtValidators#createDefaultWithValidators method doesn't really help, because we can't create our own customized X509CertificateThumbprintValidator because as I mentioned in # 1, it is final class with default visibility
  3. It doesn't really use JWKs URI either that could have been passed by the other parameter when building NimbusJwtDecoder
  4. Only way is through jakarta.servlet.request.X509Certificate request attribute but this isn't documented anywhere

Context

The token I'm decoding has cnf claim and since I've upgraded to Spring Boot 3 (spring security 6), it's broken due to new X509CertificateThumbprintValidator in Spring Security 6. It seems like I can work around it with jakarta.servlet.request.X509Certificate request attribute but ideally it should use JWKs URI that we pass in as part of building NimbusJwtValidator

@edmundham edmundham added status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels May 17, 2025
@jzheaux jzheaux self-assigned this May 22, 2025
@jzheaux
Copy link
Contributor

jzheaux commented May 22, 2025

Thanks for the suggestion, @edmundham. (In case DPoP is what you are after, I'm including the link at the top. The explanation that follows assumes that this isn't what you are referring to)

I agree that it could be helpful to have a validator that retrieved the JWKs from a JWKs URI.

It seems like I can work around it with jakarta.servlet.request.X509Certificate request attribute but ideally it should use JWKs URI that we pass in as part of building NimbusJwtValidator

I think there might be some confusion here, though. That request attribute is the result of a Servlet container (like Tomcat) validating proof-of-possession of a client cert's private key. For example, it's often the result of a successful mTLS handshake. It's not something to be "worked around", say, by populating that request attribute on your own.

If the validator were to use a JWKs URI, it would only be to provide more options for obtaining the public JWK that the cnf refers to, but it would not remove the need to validate the client's possession of the paired private key. Because mTLS proves that possession already, the validateor checks the cnf claim against the associated X509Certificate.

If you want to validate a cnf claim in a way other than mTLS, you would need to provide a mechanism to send a nonce to the client and have the client sign that nonce with their private key. Then you can verify that signed nonce against the public key that you derived.

In short, we could make this public, but there would still be a fair amount of work on your part to prove possession if you aren't planning on using the mTLS X509Certificate.

Alternativately, you can consider using Spring Security's DPoP support. This requires the client to provide a client-signed proof that accompanies the bearer token, removing the need for the resource server to rely on mTLS or ask the client to sign a nonce. DPoP verifies the client signature as well as the bearer token signature.

Does it sound like one of these approaches will work for you?

@jzheaux jzheaux added status: waiting-for-feedback We need additional information before we can continue in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) and removed status: waiting-for-triage An issue we've not yet triaged labels May 22, 2025
@edmundham
Copy link
Author

Hi @jzheaux , Thanks for the detailed explanation. Yes you are correct, I didn't really have full understanding of cnf and after a bit of research on my own it'll have to be setup end to end on our side.

In the meantime it would still be better to have X509CertificateThumbprintValidator extendable because if you look at JwtValdiators#createDefaultWithValidators https://github.com/spring-projects/spring-security/blob/6.4.6/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtValidators.java#L89 it checks whether X509CertificateThumbprintValidator is in the parameter or not. However, we can't put X509CertificateThumbprintValidator anyway because it's a final with default visibility. It would be great if we can at least customize it.

My intention is that I still want to use JwtValidators#createDefaultWithValidators because I don't want to customize everything, but just add a few customization on top of existing default validators provided from Spring Security.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels May 23, 2025
@jzheaux
Copy link
Contributor

jzheaux commented May 28, 2025

Great, @edmundham, let's take a look together. I'll close this in favor of #17178

@jzheaux jzheaux closed this as completed May 28, 2025
@jzheaux jzheaux added status: duplicate A duplicate of another issue and removed status: feedback-provided Feedback has been provided labels May 28, 2025
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

No branches or pull requests

3 participants