Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,23 @@ internal async ValueTask<TokenValidationResult> ValidateJWSAsync(

if (validationParameters.SignatureValidator != null || validationParameters.SignatureValidatorUsingConfiguration != null)
{
var validatedToken = ValidateSignatureUsingDelegates(jsonWebToken, validationParameters);
var validatedToken = ValidateSignatureUsingDelegates(jsonWebToken, validationParameters, configuration);
tokenValidationResult = await ValidateTokenPayloadAsync(
validatedToken,
validationParameters,
configuration).ConfigureAwait(false);

Validators.ValidateIssuerSecurityKey(validatedToken.SigningKey, validatedToken, validationParameters);
Validators.ValidateIssuerSecurityKey(validatedToken.SigningKey, validatedToken, validationParameters, configuration);
}
else if (validationParameters.SignatureValidatorWithToken != null
&& ValidateSignatureUsingTokenDelegate(jsonWebToken, validationParameters, configuration) is { } delegateValidatedToken)
{
tokenValidationResult = await ValidateTokenPayloadAsync(
delegateValidatedToken,
validationParameters,
configuration).ConfigureAwait(false);

Validators.ValidateIssuerSecurityKey(delegateValidatedToken.SigningKey, delegateValidatedToken, validationParameters, configuration);
}
else
{
Expand Down Expand Up @@ -436,12 +446,10 @@ internal static bool ValidateSignature(JsonWebToken jsonWebToken, SecurityKey ke
}
}

private static JsonWebToken ValidateSignatureUsingDelegates(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters)
private static JsonWebToken ValidateSignatureUsingDelegates(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
{
if (validationParameters.SignatureValidatorUsingConfiguration != null)
{
// TODO - get configuration from validationParameters
BaseConfiguration configuration = null;
var validatedToken = validationParameters.SignatureValidatorUsingConfiguration(jsonWebToken.EncodedToken, validationParameters, configuration);
if (validatedToken == null)
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
Expand All @@ -466,6 +474,43 @@ private static JsonWebToken ValidateSignatureUsingDelegates(JsonWebToken jsonWeb
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
}

/// <summary>
/// Invokes the <see cref="TokenValidationParameters.SignatureValidatorWithToken"/> delegate
/// and returns the validated token if the delegate handled the signature, or <see langword="null"/>
/// if the delegate declined.
/// </summary>
private JsonWebToken ValidateSignatureUsingTokenDelegate(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
{
try
{
var delegateResult = validationParameters.SignatureValidatorWithToken(jsonWebToken, validationParameters, configuration);

if (!delegateResult.Handled)
return null;

if (delegateResult.Token is not JsonWebToken validatedJsonWebToken)
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10506, LogHelper.MarkAsNonPII(typeof(JsonWebToken)), LogHelper.MarkAsNonPII(delegateResult.Token?.GetType()), jsonWebToken)));

RecordSignatureValidationTelemetry(
TelemetryClient,
TelemetryConstants.SignatureValidationErrors.None,
jsonWebToken,
validatedJsonWebToken.SigningKey);

return validatedJsonWebToken;
}
catch
{
RecordSignatureValidationTelemetry(
TelemetryClient,
TelemetryConstants.SignatureValidationErrors.SignatureVerificationFailed,
jsonWebToken,
jsonWebToken.SigningKey);

throw;
}
}

/// <summary>
/// Validates a JWS or a JWE.
/// </summary>
Expand Down
22 changes: 22 additions & 0 deletions src/Microsoft.IdentityModel.Tokens/Delegates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,28 @@ namespace Microsoft.IdentityModel.Tokens
/// <returns>The validated <see cref="SecurityToken"/>.</returns>
public delegate SecurityToken SignatureValidatorUsingConfiguration(string token, TokenValidationParameters validationParameters, BaseConfiguration configuration);

/// <summary>
/// Validates the signature of an already-parsed token, with the ability to decline handling.
/// </summary>
/// <param name="token">The parsed <see cref="SecurityToken"/>.</param>
/// <param name="validationParameters">The <see cref="TokenValidationParameters"/> to be used for validating the token.</param>
/// <param name="configuration">The configuration required for validation.</param>
/// <returns>
/// A <see cref="SignatureValidationDelegateResult"/> indicating whether the delegate handled the
/// signature validation. Return <see cref="SignatureValidationDelegateResult.Success"/> with the
/// validated token (and <see cref="SecurityToken.SigningKey"/> set) when the delegate validates
/// the signature. Return <see cref="SignatureValidationDelegateResult.NotHandled"/> to let the
/// handler fall through to its default signature validation logic. Throw an appropriate exception
/// (e.g., <see cref="SecurityTokenInvalidSignatureException"/>) if the signature is invalid.
/// </returns>
/// <remarks>
/// This delegate is evaluated only when <see cref="TokenValidationParameters.SignatureValidator"/>
/// and <see cref="TokenValidationParameters.SignatureValidatorUsingConfiguration"/> are not set.
/// Unlike those delegates, this one receives the already-parsed <see cref="SecurityToken"/> and
/// can decline to handle the signature, allowing the handler to validate it using its built-in logic.
/// </remarks>
public delegate SignatureValidationDelegateResult SignatureValidatorWithToken(SecurityToken token, TokenValidationParameters validationParameters, BaseConfiguration configuration);

/// <summary>
/// Reads the security token.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
~Microsoft.IdentityModel.Tokens.CaseSensitiveClaimsIdentity.SecurityToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Handled.get -> bool
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.SignatureValidationDelegateResult() -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Token.get -> Microsoft.IdentityModel.Tokens.SecurityToken?
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.NotHandled.get -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Success(Microsoft.IdentityModel.Tokens.SecurityToken token) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
~virtual Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken.Invoke(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.BaseConfiguration configuration) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.get -> Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult other) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(object obj) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.GetHashCode() -> int
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator ==(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator !=(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
~Microsoft.IdentityModel.Tokens.CaseSensitiveClaimsIdentity.SecurityToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Handled.get -> bool
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.SignatureValidationDelegateResult() -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Token.get -> Microsoft.IdentityModel.Tokens.SecurityToken?
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.NotHandled.get -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Success(Microsoft.IdentityModel.Tokens.SecurityToken token) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
~virtual Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken.Invoke(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.BaseConfiguration configuration) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.get -> Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult other) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(object obj) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.GetHashCode() -> int
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator ==(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator !=(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
~Microsoft.IdentityModel.Tokens.CaseSensitiveClaimsIdentity.SecurityToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Handled.get -> bool
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.SignatureValidationDelegateResult() -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Token.get -> Microsoft.IdentityModel.Tokens.SecurityToken?
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.NotHandled.get -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Success(Microsoft.IdentityModel.Tokens.SecurityToken token) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
~virtual Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken.Invoke(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.BaseConfiguration configuration) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.get -> Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult other) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(object obj) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.GetHashCode() -> int
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator ==(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator !=(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
~Microsoft.IdentityModel.Tokens.CaseSensitiveClaimsIdentity.SecurityToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Handled.get -> bool
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.SignatureValidationDelegateResult() -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Token.get -> Microsoft.IdentityModel.Tokens.SecurityToken?
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.NotHandled.get -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Success(Microsoft.IdentityModel.Tokens.SecurityToken token) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
~virtual Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken.Invoke(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.BaseConfiguration configuration) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.get -> Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult other) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(object obj) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.GetHashCode() -> int
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator ==(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator !=(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
~Microsoft.IdentityModel.Tokens.CaseSensitiveClaimsIdentity.SecurityToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Handled.get -> bool
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.SignatureValidationDelegateResult() -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Token.get -> Microsoft.IdentityModel.Tokens.SecurityToken?
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.NotHandled.get -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Success(Microsoft.IdentityModel.Tokens.SecurityToken token) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
~virtual Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken.Invoke(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.BaseConfiguration configuration) -> Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.get -> Microsoft.IdentityModel.Tokens.SignatureValidatorWithToken
Microsoft.IdentityModel.Tokens.TokenValidationParameters.SignatureValidatorWithToken.set -> void
Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult other) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.Equals(object obj) -> bool
override Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.GetHashCode() -> int
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator ==(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
static Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult.operator !=(Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult left, Microsoft.IdentityModel.Tokens.SignatureValidationDelegateResult right) -> bool
Loading