Skip to content

Commit

Permalink
Added SigningKeyValidationResult
Browse files Browse the repository at this point in the history
  • Loading branch information
iNinja committed Jun 27, 2024
1 parent 3ce64bb commit 32e3d5e
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
#nullable enable
namespace Microsoft.IdentityModel.Tokens
{
/// <summary>
/// Contains the result of validating the <see cref="SecurityKey"/> used to sign a <see cref="SecurityToken"/>.
/// The <see cref="TokenValidationResult"/> contains a collection of <see cref="ValidationResult"/> for each step in the token validation.
/// </summary>
internal class SigningKeyValidationResult : ValidationResult
{
private Exception? _exception;

/// <summary>
/// Creates an instance of <see cref="SigningKeyValidationResult"/>
/// </summary>
/// <paramref name="signingKey"/> is the security key that was validated successfully.
public SigningKeyValidationResult(SecurityKey? signingKey)
: base(ValidationFailureType.ValidationSucceeded)
{
SigningKey = signingKey;
IsValid = true;
}

/// <summary>
/// Creates an instance of <see cref="SigningKeyValidationResult"/>
/// </summary>
/// <paramref name="signingKey"/> is the security key that was intended to be validated.
/// <paramref name="validationFailure"/> is the <see cref="ValidationFailureType"/> that occurred during validation.
/// <paramref name="exceptionDetail"/> is the <see cref="ExceptionDetail"/> that occurred during validation.
public SigningKeyValidationResult(SecurityKey? signingKey, ValidationFailureType validationFailure, ExceptionDetail exceptionDetail)
: base(validationFailure, exceptionDetail)
{
SigningKey = signingKey;
IsValid = false;
}

/// <summary>
/// Gets the <see cref="Exception"/> that occurred during validation.
/// </summary>
public override Exception? Exception
{
get
{
if (_exception != null || ExceptionDetail == null)
return _exception;

HasValidOrExceptionWasRead = true;
_exception = ExceptionDetail.GetException();
if (_exception is SecurityTokenInvalidSigningKeyException securityTokenInvalidSigningKeyException)
{
securityTokenInvalidSigningKeyException.SigningKey = SigningKey;
securityTokenInvalidSigningKeyException.ExceptionDetail = ExceptionDetail;
securityTokenInvalidSigningKeyException.Source = "Microsoft.IdentityModel.Tokens";
}

return _exception;
}
}

/// <summary>
/// Gets the security key that was validated or intended to be validated.
/// </summary>
public SecurityKey? SigningKey { get; }
}
}
#nullable restore
66 changes: 66 additions & 0 deletions test/Microsoft.IdentityModel.TestUtils/IdentityComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,72 @@ internal static bool AreAudienceValidationResultsEqual(
return context.Merge(localContext);
}

public static bool AreSigningKeyValidationResultsEqual(object object1, object object2, CompareContext context)
{
var localContext = new CompareContext(context);
if (!ContinueCheckingEquality(object1, object2, context))
return context.Merge(localContext);

return AreSigningKeyValidationResultsEqual(
object1 as SigningKeyValidationResult,
object2 as SigningKeyValidationResult,
"SigningKeyValidationResult1",
"SigningKeyValidationResult2",
null,
context);
}

internal static bool AreSigningKeyValidationResultsEqual(
SigningKeyValidationResult signingKeyValidationResult1,
SigningKeyValidationResult signingKeyValidationResult2,
string name1,
string name2,
string stackPrefix,
CompareContext context)
{
var localContext = new CompareContext(context);

AreSecurityKeysEqual(signingKeyValidationResult1.SigningKey, signingKeyValidationResult2.SigningKey, localContext);

if (!ContinueCheckingEquality(signingKeyValidationResult1, signingKeyValidationResult2, localContext))
return context.Merge(localContext);

if (signingKeyValidationResult1.IsValid != signingKeyValidationResult2.IsValid)
localContext.Diffs.Add($"SigningKeyValidationResult1.IsValid: {signingKeyValidationResult2.IsValid} != SigningKeyValidationResult2.IsValid: {signingKeyValidationResult2.IsValid}");

if (signingKeyValidationResult1.ValidationFailureType != signingKeyValidationResult2.ValidationFailureType)
localContext.Diffs.Add($"SigningKeyValidationResult1.ValidationFailureType: {signingKeyValidationResult1.ValidationFailureType} != SigningKeyValidationResult2.ValidationFailureType: {signingKeyValidationResult2.ValidationFailureType}");

// true => both are not null.
if (ContinueCheckingEquality(signingKeyValidationResult1.Exception, signingKeyValidationResult2.Exception, localContext))
{
AreStringsEqual(
signingKeyValidationResult1.Exception.Message,
signingKeyValidationResult2.Exception.Message,
$"({name1})signingKeyValidationResult1.Exception.Message",
$"({name2})signingKeyValidationResult2.Exception.Message",
localContext);

AreStringsEqual(
signingKeyValidationResult1.Exception.Source,
signingKeyValidationResult2.Exception.Source,
$"({name1})signingKeyValidationResult1.Exception.Source",
$"({name2})signingKeyValidationResult2.Exception.Source",
localContext);

if (!string.IsNullOrEmpty(stackPrefix))
AreStringPrefixesEqual(
signingKeyValidationResult1.Exception.StackTrace.Trim(),
signingKeyValidationResult2.Exception.StackTrace.Trim(),
$"({name1})signingKeyValidationResult1.Exception.StackTrace",
$"({name2})signingKeyValidationResult2.Exception.StackTrace",
stackPrefix.Trim(),
localContext);
}

return context.Merge(localContext);
}

public static bool AreJArraysEqual(object object1, object object2, CompareContext context)
{
var localContext = new CompareContext(context);
Expand Down

0 comments on commit 32e3d5e

Please sign in to comment.