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

Extensibility tests: Issuer signing key - JWT, SAML and SAML2 #3029

Merged
Merged
Show file tree
Hide file tree
Changes from 8 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 @@ -353,13 +353,27 @@ await ValidateJWSAsync(actorToken, actorParameters, configuration, callContext,
return signatureValidationResult.UnwrapError().AddStackFrame(signatureValidationFailureStackFrame);
}

ValidationResult<ValidatedSigningKeyLifetime> issuerSigningKeyValidationResult =
validationParameters.IssuerSigningKeyValidator(
ValidationResult<ValidatedSigningKeyLifetime> issuerSigningKeyValidationResult;

try
{
issuerSigningKeyValidationResult = validationParameters.IssuerSigningKeyValidator(
jsonWebToken.SigningKey, jsonWebToken, validationParameters, configuration, callContext);
if (!issuerSigningKeyValidationResult.IsValid)

if (!issuerSigningKeyValidationResult.IsValid)
return issuerSigningKeyValidationResult.UnwrapError().AddCurrentStackFrame();
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
StackFrame issuerSigningKeyValidationFailureStackFrame = StackFrames.IssuerSigningKeyValidationFailed ??= new StackFrame(true);
return issuerSigningKeyValidationResult.UnwrapError().AddStackFrame(issuerSigningKeyValidationFailureStackFrame);
return new IssuerSigningKeyValidationError(
new MessageDetail(TokenLogMessages.IDX10274),
ValidationFailureType.IssuerSigningKeyValidatorThrew,
typeof(SecurityTokenInvalidSigningKeyException),
ValidationError.GetCurrentStackFrame(),
jsonWebToken.SigningKey,
ex);
}

return new ValidatedToken(jsonWebToken, this, validationParameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,32 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
return signatureValidationResult.UnwrapError().AddStackFrame(StackFrames.SignatureValidationFailed);
}

ValidationResult<ValidatedSigningKeyLifetime> issuerSigningKeyValidationResult = validationParameters.IssuerSigningKeyValidator(
samlToken.SigningKey,
samlToken,
validationParameters,
null,
callContext);
ValidationResult<ValidatedSigningKeyLifetime> issuerSigningKeyValidationResult;

try
{
issuerSigningKeyValidationResult = validationParameters.IssuerSigningKeyValidator(
samlToken.SigningKey,
samlToken,
validationParameters,
null,
callContext);

if (!issuerSigningKeyValidationResult.IsValid)
return issuerSigningKeyValidationResult.UnwrapError().AddCurrentStackFrame();
if (!issuerSigningKeyValidationResult.IsValid)
return issuerSigningKeyValidationResult.UnwrapError().AddCurrentStackFrame();
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
return new IssuerSigningKeyValidationError(
new MessageDetail(Tokens.LogMessages.IDX10274),
ValidationFailureType.IssuerSigningKeyValidatorThrew,
typeof(SecurityTokenInvalidSigningKeyException),
ValidationError.GetCurrentStackFrame(),
samlToken.SigningKey,
ex);
}

return new ValidatedToken(samlToken, this, validationParameters);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,31 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
return signatureValidationResult.UnwrapError().AddStackFrame(StackFrames.SignatureValidationFailed);
}

var issuerSigningKeyValidationResult = validationParameters.IssuerSigningKeyValidator(
samlToken.SigningKey,
samlToken,
validationParameters,
null,
callContext);
ValidationResult<ValidatedSigningKeyLifetime> issuerSigningKeyValidationResult;

if (!issuerSigningKeyValidationResult.IsValid)
try
{
issuerSigningKeyValidationResult = validationParameters.IssuerSigningKeyValidator(
samlToken.SigningKey,
samlToken,
validationParameters,
null,
callContext);

if (!issuerSigningKeyValidationResult.IsValid)
return issuerSigningKeyValidationResult.UnwrapError().AddCurrentStackFrame();
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
StackFrames.IssuerSigningKeyValidationFailed ??= new StackFrame(true);
return issuerSigningKeyValidationResult.UnwrapError().AddStackFrame(StackFrames.IssuerSigningKeyValidationFailed);
return new IssuerSigningKeyValidationError(
new MessageDetail(Tokens.LogMessages.IDX10274),
ValidationFailureType.IssuerSigningKeyValidatorThrew,
typeof(SecurityTokenInvalidSigningKeyException),
ValidationError.GetCurrentStackFrame(),
samlToken.SigningKey,
ex);
}

return new ValidatedToken(samlToken, this, validationParameters);
Expand Down
10 changes: 4 additions & 6 deletions src/Microsoft.IdentityModel.Tokens/InternalAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10002 = "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'." -> string
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10268 = "IDX10268: Unable to validate audience, validationParameters.ValidAudiences.Count == 0." -> string
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10269 = "IDX10269: IssuerValidationDelegate threw an exception, see inner exception." -> string
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10271 = "IDX10271: LifetimeValidationDelegate threw an exception, see inner exception." -> string
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10275 = "IDX10275: TokenTypeValidationDelegate threw an exception, see inner exception." -> string
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10274 = "IDX10274: IssuerSigningKeyValidationDelegate threw an exception, see inner exception." -> string
Microsoft.IdentityModel.Tokens.AlgorithmValidationError
Microsoft.IdentityModel.Tokens.AlgorithmValidationError.AlgorithmValidationError(Microsoft.IdentityModel.Tokens.MessageDetail messageDetail, Microsoft.IdentityModel.Tokens.ValidationFailureType validationFailureType, System.Type exceptionType, System.Diagnostics.StackFrame stackFrame, string invalidAlgorithm, System.Exception innerException = null) -> void
Microsoft.IdentityModel.Tokens.AlgorithmValidationError.InvalidAlgorithm.get -> string
Expand All @@ -15,7 +14,7 @@ Microsoft.IdentityModel.Tokens.AudienceValidationError.ValidAudiences.set -> voi
Microsoft.IdentityModel.Tokens.IssuerSigningKeyValidationError
Microsoft.IdentityModel.Tokens.IssuerSigningKeyValidationError.InvalidSigningKey.get -> Microsoft.IdentityModel.Tokens.SecurityKey
Microsoft.IdentityModel.Tokens.IssuerSigningKeyValidationError.InvalidSigningKey.set -> void
Microsoft.IdentityModel.Tokens.IssuerSigningKeyValidationError.IssuerSigningKeyValidationError(Microsoft.IdentityModel.Tokens.MessageDetail messageDetail, System.Type exceptionType, System.Diagnostics.StackFrame stackFrame, Microsoft.IdentityModel.Tokens.SecurityKey invalidSigningKey, Microsoft.IdentityModel.Tokens.ValidationFailureType failureType = null, System.Exception innerException = null) -> void
Microsoft.IdentityModel.Tokens.IssuerSigningKeyValidationError.IssuerSigningKeyValidationError(Microsoft.IdentityModel.Tokens.MessageDetail messageDetail, Microsoft.IdentityModel.Tokens.ValidationFailureType validationFailureType, System.Type exceptionType, System.Diagnostics.StackFrame stackFrame, Microsoft.IdentityModel.Tokens.SecurityKey invalidSigningKey, System.Exception innerException = null) -> void
Microsoft.IdentityModel.Tokens.IssuerValidationError.InvalidIssuer.get -> string
Microsoft.IdentityModel.Tokens.IssuerValidationError.IssuerValidationError(Microsoft.IdentityModel.Tokens.MessageDetail messageDetail, Microsoft.IdentityModel.Tokens.ValidationFailureType validationFailureType, System.Type exceptionType, System.Diagnostics.StackFrame stackFrame, string invalidIssuer, System.Exception innerException = null) -> void
Microsoft.IdentityModel.Tokens.IssuerValidationSource.IssuerMatchedConfiguration = 1 -> Microsoft.IdentityModel.Tokens.IssuerValidationSource
Expand All @@ -30,7 +29,7 @@ Microsoft.IdentityModel.Tokens.TokenValidationParameters.TimeProvider.get -> Sys
Microsoft.IdentityModel.Tokens.TokenValidationParameters.TimeProvider.set -> void
Microsoft.IdentityModel.Tokens.ValidationError.AddCurrentStackFrame(string filePath = "", int lineNumber = 0, int skipFrames = 1) -> Microsoft.IdentityModel.Tokens.ValidationError
Microsoft.IdentityModel.Tokens.ValidationError.GetException(System.Type exceptionType, System.Exception innerException) -> System.Exception
Microsoft.IdentityModel.Tokens.ValidationError.ValidationError(Microsoft.IdentityModel.Tokens.MessageDetail messageDetail, Microsoft.IdentityModel.Tokens.ValidationFailureType failureType, System.Type exceptionType, System.Diagnostics.StackFrame stackFrame, System.Exception innerException = null) -> void
Microsoft.IdentityModel.Tokens.ValidationError.ValidationError(Microsoft.IdentityModel.Tokens.MessageDetail messageDetail, Microsoft.IdentityModel.Tokens.ValidationFailureType validationFailureType, System.Type exceptionType, System.Diagnostics.StackFrame stackFrame, System.Exception innerException = null) -> void
Microsoft.IdentityModel.Tokens.ValidationParameters.TokenTypeValidator.get -> Microsoft.IdentityModel.Tokens.TokenTypeValidationDelegate
Microsoft.IdentityModel.Tokens.ValidationParameters.TokenTypeValidator.set -> void
Microsoft.IdentityModel.Tokens.ValidationResult<TResult>.Error.get -> Microsoft.IdentityModel.Tokens.ValidationError
Expand All @@ -42,12 +41,11 @@ override Microsoft.IdentityModel.Tokens.TokenTypeValidationError.GetException()
static Microsoft.IdentityModel.Tokens.IssuerSigningKeyValidationError.NullParameter(string parameterName, System.Diagnostics.StackFrame stackFrame) -> Microsoft.IdentityModel.Tokens.IssuerSigningKeyValidationError
static Microsoft.IdentityModel.Tokens.Utility.SerializeAsSingleCommaDelimitedString(System.Collections.Generic.IList<string> strings) -> string
static Microsoft.IdentityModel.Tokens.ValidationError.GetCurrentStackFrame(string filePath = "", int lineNumber = 0, int skipFrames = 1) -> System.Diagnostics.StackFrame
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.IssuerSigningKeyValidatorThrew -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.IssuerValidatorThrew -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.LifetimeValidatorThrew -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.NoTokenAudiencesProvided -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.NoValidationParameterAudiencesProvided -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.SignatureAlgorithmValidationFailed -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.TokenExceedsMaximumSize -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.TokenIsNotSigned -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.TokenTypeValidatorThrew -> Microsoft.IdentityModel.Tokens.ValidationFailureType
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.XmlValidationFailed -> Microsoft.IdentityModel.Tokens.ValidationFailureType
2 changes: 1 addition & 1 deletion src/Microsoft.IdentityModel.Tokens/LogMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ internal static class LogMessages
public const string IDX10267 = "IDX10267: '{0}' has been called by a derived class '{1}' which has not implemented this method. For this call graph to succeed, '{1}' will need to implement '{0}'.";
public const string IDX10268 = "IDX10268: Unable to validate audience, validationParameters.ValidAudiences.Count == 0.";
public const string IDX10269 = "IDX10269: IssuerValidationDelegate threw an exception, see inner exception.";

public const string IDX10274 = "IDX10274: IssuerSigningKeyValidationDelegate threw an exception, see inner exception.";

// 10500 - SignatureValidation
public const string IDX10500 = "IDX10500: Signature validation failed. No security keys were provided to validate the signature.";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.


iNinja marked this conversation as resolved.
Show resolved Hide resolved
using System.Diagnostics;
using System;

#nullable enable
namespace Microsoft.IdentityModel.Tokens
{
internal class IssuerSigningKeyValidationError : ValidationError
{
internal IssuerSigningKeyValidationError(
MessageDetail messageDetail,
ValidationFailureType validationFailureType,
Type exceptionType,
StackFrame stackFrame,
SecurityKey? invalidSigningKey,
Exception? innerException = null)
: base(messageDetail, validationFailureType, exceptionType, stackFrame, innerException)
{
InvalidSigningKey = invalidSigningKey;
}

internal override Exception GetException()
{
if (ExceptionType == typeof(SecurityTokenInvalidSigningKeyException))
{
SecurityTokenInvalidSigningKeyException? exception = new(MessageDetail.Message, InnerException)
{
SigningKey = InvalidSigningKey
};
exception.SetValidationError(this);

return exception;
}

return base.GetException();
}

iNinja marked this conversation as resolved.
Show resolved Hide resolved

internal static new IssuerSigningKeyValidationError NullParameter(string parameterName, StackFrame stackFrame) => new(
MessageDetail.NullParameter(parameterName),
ValidationFailureType.NullArgument,
typeof(SecurityTokenArgumentNullException),
stackFrame,
null); // InvalidSigningKey

protected SecurityKey? InvalidSigningKey { get; set; }
}
}
#nullable restore
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ internal class ValidationError
/// Creates an instance of <see cref="ValidationError"/>
/// </summary>
/// <param name="messageDetail"/> contains information about the exception that is used to generate the exception message.
/// <param name="failureType"/> is the type of validation failure that occurred.
/// <param name="validationFailureType"/> is the type of validation failure that occurred.
/// <param name="exceptionType"/> is the type of exception that occurred.
/// <param name="stackFrame"/> is the stack frame where the exception occurred.
/// <param name="innerException"/> is the inner exception that occurred.
internal ValidationError(
MessageDetail messageDetail,
ValidationFailureType failureType,
ValidationFailureType validationFailureType,
Type exceptionType,
StackFrame stackFrame,
Exception? innerException = null)
{
InnerException = innerException;
MessageDetail = messageDetail;
_exceptionType = exceptionType;
FailureType = failureType;
FailureType = validationFailureType;
StackFrames = new List<StackFrame>(4)
{
stackFrame
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ private class SignatureAlgorithmValidationFailure : ValidationFailureType { inte
/// <summary>
/// Defines a type that represents that signing key validation failed.
/// </summary>
public static readonly ValidationFailureType SigningKeyValidationFailed = new SigningKeyValidationFailure("SigningKeyValidationFailed");
private class SigningKeyValidationFailure : ValidationFailureType { internal SigningKeyValidationFailure(string name) : base(name) { } }
public static readonly ValidationFailureType SigningKeyValidationFailed = new IssuerSigningKeyValidationFailure("IssuerSigningKeyValidationFailed");
private class IssuerSigningKeyValidationFailure : ValidationFailureType { internal IssuerSigningKeyValidationFailure(string name) : base(name) { } }

/// <summary>
/// Defines a type that represents that lifetime validation failed.
Expand Down Expand Up @@ -134,5 +134,10 @@ private class XmlValidationFailure : ValidationFailureType { internal XmlValidat
/// </summary>
public static readonly ValidationFailureType IssuerValidatorThrew = new IssuerValidatorFailure("IssuerValidatorThrew");
private class IssuerValidatorFailure : ValidationFailureType { internal IssuerValidatorFailure(string name) : base(name) { } }

/// <summary>
/// Defines a type that represents that the issuer signing key validation delegate threw an exception.
/// </summary>
public static readonly ValidationFailureType IssuerSigningKeyValidatorThrew = new IssuerSigningKeyValidationFailure("IssuerSigningKeyValidatorThrew");
brentschmaltz marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading
Loading