Skip to content

Add TryValidateSignature and SignatureValidatorWithToken delegate#3483

Closed
iNinja wants to merge 3 commits into
dev8xfrom
iinglese/try-validate-signature
Closed

Add TryValidateSignature and SignatureValidatorWithToken delegate#3483
iNinja wants to merge 3 commits into
dev8xfrom
iinglese/try-validate-signature

Conversation

@iNinja

@iNinja iNinja commented May 12, 2026

Copy link
Copy Markdown
Contributor

Add TryValidateSignature and SignatureValidatorWithToken delegate

Summary

This PR adds two public APIs to support scenarios where a SignatureValidatorUsingConfiguration delegate needs to call back into the handler's own signature validation logic for algorithms it does not handle directly.

Changes

JsonWebTokenHandler.TryValidateSignature

A new public instance method that validates a JWT signature against a single specified key:

public bool TryValidateSignature(
    JsonWebToken jsonWebToken,
    SecurityKey key,
    TokenValidationParameters validationParameters)
  • Validates algorithm, creates a SignatureProvider, and verifies the signature
  • Uses the handler's telemetry infrastructure
  • The caller is responsible for key resolution — this method validates a single key
  • Throws on null arguments, algorithm validation failure, or inability to create a signature provider
  • Returns false if the signature does not match

SignatureValidatorWithToken delegate

A new delegate on TokenValidationParameters that receives the already-parsed SecurityToken instead of a raw string:

public delegate SecurityToken SignatureValidatorWithToken(
    SecurityToken token,
    TokenValidationParameters validationParameters,
    BaseConfiguration configuration);
// On TokenValidationParameters:
public SignatureValidatorWithToken SignatureValidatorWithToken { get; set; }
  • Takes priority over SignatureValidatorUsingConfiguration and SignatureValidator when set
  • Avoids re-parsing the token string, since the handler has already parsed it
  • Receives the resolved BaseConfiguration (OIDC metadata), enabling the delegate to access configuration.JsonWebKeySet.Keys for key resolution

Configuration passthrough fix

The existing ValidateSignatureUsingDelegates method was not passing the resolved BaseConfiguration to the signature validation delegates (hardcoded to null with a TODO comment). This has been fixed — all three delegates now receive the configuration that was already resolved upstream.

Usage example

var handler = new JsonWebTokenHandler();

tvp.SignatureValidatorWithToken = (token, tvp, configuration) =>
{
    var jwt = (JsonWebToken)token;
    
    if (IsCustomAlgorithm(jwt.Alg))
    {
        // Handle custom algorithm directly
        VerifyWithCustomProvider(jwt, configuration);
    }
    else
    {
        // Fall back to the handler for standard algorithms
        var key = ResolveKey(jwt, configuration);
        if (!handler.TryValidateSignature(jwt, key, tvp))
            throw new SecurityTokenInvalidSignatureException("Signature validation failed.");
        jwt.SigningKey = key;
    }
    
    return jwt;
};

Tests

8 tests covering:

  • Valid RSA signature → returns true
  • Wrong key → returns false
  • ECDSA key → returns true
  • Algorithm mismatch (ECDSA key vs RSA token) → returns false
  • Null token/key/validationParameters → throws ArgumentNullException
  • End-to-end delegate pattern using SignatureValidatorWithToken + TryValidateSignature

Add a public TryValidateSignature instance method on JsonWebTokenHandler
that validates a JWT signature against a single specified key, using the
handler's telemetry infrastructure.

Add SignatureValidatorWithToken delegate to TokenValidationParameters
that receives the already-parsed SecurityToken instead of a raw string,
avoiding the need to re-parse the token. Takes priority over
SignatureValidatorUsingConfiguration and SignatureValidator when set.

These methods are intended for use within signature validation delegates,
enabling the delegate to call back into the handler's signature validation
logic for algorithms it does not handle directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@iNinja iNinja requested a review from a team as a code owner May 12, 2026 15:19
@iNinja iNinja requested a review from Copilot May 12, 2026 15:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces new extensibility points for JWT signature validation in Microsoft.IdentityModel.JsonWebTokens / Microsoft.IdentityModel.Tokens, enabling custom signature validators to reuse the handler’s built-in signature verification without re-parsing tokens.

Changes:

  • Adds JsonWebTokenHandler.TryValidateSignature(JsonWebToken, SecurityKey, TokenValidationParameters) for verifying a JWS signature against a single resolved key (with telemetry).
  • Adds the SignatureValidatorWithToken delegate + TokenValidationParameters.SignatureValidatorWithToken property to support signature validation using an already-parsed SecurityToken.
  • Updates JsonWebTokenHandler to (a) prefer SignatureValidatorWithToken when set and (b) pass the resolved BaseConfiguration into signature delegates; updates PublicAPI baselines and adds new unit tests.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.TryValidateSignatureTests.cs Adds coverage for TryValidateSignature (valid/invalid key, alg mismatch, null args) and basic e2e delegate usage.
src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs Adds SignatureValidatorWithToken property and copies it in the TVP copy constructor.
src/Microsoft.IdentityModel.Tokens/Delegates.cs Introduces the new SignatureValidatorWithToken delegate type.
src/Microsoft.IdentityModel.JsonWebTokens/PublicAPI.Unshipped.txt Adds the new JsonWebTokenHandler.TryValidateSignature public API entry.
src/Microsoft.IdentityModel.Tokens/PublicAPI/*/PublicAPI.Unshipped.txt Adds new public API entries for SignatureValidatorWithToken and the TVP property across TFMs.
src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.ValidateToken.cs Wires SignatureValidatorWithToken, passes BaseConfiguration through to signature delegates, and adds the new public TryValidateSignature method.

iNinja and others added 2 commits May 12, 2026 16:36
…n passthrough tests

- Update XML docs to reference both SignatureValidatorWithToken and
  SignatureValidatorUsingConfiguration delegates
- Clarify throwing vs false-return semantics in remarks
- Add test verifying SignatureValidatorWithToken receives resolved
  BaseConfiguration from ConfigurationManager
- Add test verifying SignatureValidatorUsingConfiguration receives
  resolved BaseConfiguration from ConfigurationManager

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The delegate code path in ValidateJWSAsync called the 3-parameter
ValidateIssuerSecurityKey overload, which passes configuration as null.
This silently skipped IssuerSigningKeyValidatorUsingConfiguration checks
(e.g. AAD signing key issuer validation via EnableAadSigningKeyIssuerValidation).

Changed to the 4-parameter overload that passes the resolved
BaseConfiguration, matching the non-delegate code path behaviour.

Added test verifying IssuerSigningKeyValidatorUsingConfiguration receives
the resolved configuration when a signature delegate is used.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@iNinja

iNinja commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

Abandoning in favour of a simpler approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants