Skip to content

Commit

Permalink
Added internal virtual on TokenHandler
Browse files Browse the repository at this point in the history
Add AadIssuer with ValidationParameters
Added tests to AadIssuerValidator for ValidationParameters
  • Loading branch information
HP712 authored and Brent Schmaltz committed Jan 14, 2025
1 parent 075a627 commit 0f6c5a3
Show file tree
Hide file tree
Showing 24 changed files with 782 additions and 93 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
override Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
override Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(string token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.CreateToken(string payload, Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor tokenDescriptor) -> string
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.EncryptToken(byte[] innerTokenUtf8Bytes, Microsoft.IdentityModel.Tokens.EncryptingCredentials encryptingCredentials, string compressionAlgorithm, System.Collections.Generic.IDictionary<string, object> additionalHeaderClaims, string tokenType, bool includeKeyIdInHeader) -> string
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.EncryptToken(byte[] innerTokenUtf8Bytes, Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor tokenDescriptor) -> string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public partial class JsonWebTokenHandler : TokenHandler
/// <exception cref="ArgumentException">Returned if 'token.Length' is greater than <see cref="TokenHandler.MaximumTokenSizeInBytes"/>.</exception>
/// <exception cref="SecurityTokenMalformedException">Returned if <paramref name="token"/> is not a valid <see cref="JsonWebToken"/>, <see cref="ReadToken(string, CallContext)"/></exception>
/// <exception cref="SecurityTokenMalformedException">Returned if the validationParameters.TokenReader delegate is not able to parse/read the token as a valid <see cref="JsonWebToken"/>, <see cref="ReadToken(string, CallContext)"/></exception>
internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
internal override async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
string token,
ValidationParameters validationParameters,
CallContext callContext,
Expand Down Expand Up @@ -91,7 +91,7 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
}

/// <inheritdoc/>
internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
internal override async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
SecurityToken token,
ValidationParameters validationParameters,
CallContext callContext,
Expand Down Expand Up @@ -420,7 +420,7 @@ await ValidateJWSAsync(actorToken, actorParameters, configuration, callContext,
try
{
issuerSigningKeyValidationResult = validationParameters.IssuerSigningKeyValidator(
jsonWebToken.SigningKey, jsonWebToken, validationParameters, configuration, callContext);
jsonWebToken.SigningKey, jsonWebToken, validationParameters, callContext);

if (!issuerSigningKeyValidationResult.IsValid)
return issuerSigningKeyValidationResult.UnwrapError().AddCurrentStackFrame();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidatedConditions
Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidatedConditions.ValidatedConditions(string ValidatedAudience, Microsoft.IdentityModel.Tokens.ValidatedLifetime? ValidatedLifetime) -> void
Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidatedConditions.ValidatedLifetime.get -> Microsoft.IdentityModel.Tokens.ValidatedLifetime?
Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidatedConditions.ValidatedLifetime.set -> void
Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateTokenAsync(Microsoft.IdentityModel.Tokens.SecurityToken securityToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateTokenAsync(string token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
Microsoft.IdentityModel.Tokens.Saml.SamlValidationError
Microsoft.IdentityModel.Tokens.Saml.SamlValidationError.SamlValidationError(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.Saml2.Saml2SecurityTokenHandler.CreateClaimsIdentity(Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityToken samlToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, string issuer) -> System.Security.Claims.ClaimsIdentity
Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.StackFrames
Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateTokenAsync(Microsoft.IdentityModel.Tokens.SecurityToken securityToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateTokenAsync(string token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
Microsoft.IdentityModel.Tokens.Saml2.Saml2ValidationError
Microsoft.IdentityModel.Tokens.Saml2.Saml2ValidationError.Saml2ValidationError(Microsoft.IdentityModel.Tokens.MessageDetail messageDetail, Microsoft.IdentityModel.Tokens.ValidationFailureType validationFailureType, System.Type exceptionType, System.Diagnostics.StackFrame stackFrame, System.Exception innerException = null) -> void
override Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.CreateClaimsIdentityInternal(Microsoft.IdentityModel.Tokens.SecurityToken securityToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, string issuer) -> System.Security.Claims.ClaimsIdentity
override Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateTokenAsync(Microsoft.IdentityModel.Tokens.SecurityToken securityToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
override Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateTokenAsync(string token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
override Microsoft.IdentityModel.Tokens.Saml.SamlValidationError.GetException() -> System.Exception
override Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.CreateClaimsIdentityInternal(Microsoft.IdentityModel.Tokens.SecurityToken securityToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, string issuer) -> System.Security.Claims.ClaimsIdentity
override Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateTokenAsync(Microsoft.IdentityModel.Tokens.SecurityToken securityToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
override Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateTokenAsync(string token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
override Microsoft.IdentityModel.Tokens.Saml2.Saml2ValidationError.GetException() -> System.Exception
static Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.StackFrames.IssuerValidationFailed -> System.Diagnostics.StackFrame
static Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.StackFrames.SignatureValidationFailed -> System.Diagnostics.StackFrame
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Microsoft.IdentityModel.Tokens.Saml
/// </summary>
public partial class SamlSecurityTokenHandler : SecurityTokenHandler
{
internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
internal override async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
string token,
ValidationParameters validationParameters,
CallContext callContext,
Expand All @@ -34,7 +34,7 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
return await ValidateTokenAsync(tokenReadingResult.UnwrapResult(), validationParameters, callContext, cancellationToken).ConfigureAwait(false);
}

internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
internal override async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
SecurityToken securityToken,
ValidationParameters validationParameters,
CallContext callContext,
Expand Down Expand Up @@ -148,7 +148,6 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
samlToken.SigningKey,
samlToken,
validationParameters,
null,
callContext);

if (!issuerSigningKeyValidationResult.IsValid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.IdentityModel.Tokens.Saml2
/// </summary>
public partial class Saml2SecurityTokenHandler : SecurityTokenHandler
{
internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
internal override async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
string token,
ValidationParameters validationParameters,
CallContext callContext,
Expand All @@ -35,7 +35,7 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
return await ValidateTokenAsync(tokenReadingResult.UnwrapResult(), validationParameters, callContext, cancellationToken).ConfigureAwait(false);
}

internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
internal override async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
SecurityToken securityToken,
ValidationParameters validationParameters,
CallContext callContext,
Expand Down Expand Up @@ -151,7 +151,6 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
samlToken.SigningKey,
samlToken,
validationParameters,
null,
callContext);

if (!issuerSigningKeyValidationResult.IsValid)
Expand Down
3 changes: 3 additions & 0 deletions src/Microsoft.IdentityModel.Tokens/InternalAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ static Microsoft.IdentityModel.Tokens.TokenTypeValidationError.NullParameter(str
static Microsoft.IdentityModel.Tokens.Base64UrlEncoder.Decode(System.ReadOnlySpan<char> strSpan, System.Span<byte> output) -> int
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 Microsoft.IdentityModel.Tokens.Validators.ValidateIssuerSigningKey(Microsoft.IdentityModel.Tokens.SecurityKey securityKey, Microsoft.IdentityModel.Tokens.SecurityToken securityToken, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext) -> Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedSigningKeyLifetime>
static readonly Microsoft.IdentityModel.Tokens.LoggingEventId.TokenValidationFailed -> Microsoft.Extensions.Logging.EventId
static readonly Microsoft.IdentityModel.Tokens.LoggingEventId.TokenValidationSucceeded -> Microsoft.Extensions.Logging.EventId
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.AlgorithmValidatorThrew -> Microsoft.IdentityModel.Tokens.ValidationFailureType
Expand All @@ -84,3 +85,5 @@ static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.TokenIsNotS
static readonly Microsoft.IdentityModel.Tokens.ValidationFailureType.TokenReplayValidatorThrew -> 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
virtual Microsoft.IdentityModel.Tokens.TokenHandler.ValidateTokenAsync(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
virtual Microsoft.IdentityModel.Tokens.TokenHandler.ValidateTokenAsync(string token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
33 changes: 33 additions & 0 deletions src/Microsoft.IdentityModel.Tokens/TokenHandler.Internal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.IdentityModel.Tokens
{
/// <summary>
/// Defines properties shared across all security token handlers.
/// </summary>
public abstract partial class TokenHandler
{
internal virtual Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
string token,
ValidationParameters validationParameters,
CallContext callContext,
CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

internal virtual Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
SecurityToken token,
ValidationParameters validationParameters,
CallContext callContext,
CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.IdentityModel.Tokens/TokenHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Microsoft.IdentityModel.Tokens
/// <summary>
/// Defines properties shared across all security token handlers.
/// </summary>
public abstract class TokenHandler
public abstract partial class TokenHandler
{
private int _defaultTokenLifetimeInMinutes = DefaultTokenLifetimeInMinutes;
private int _maximumTokenSizeInBytes = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal class ValidationParameters
private string _nameClaimType = ClaimsIdentity.DefaultNameClaimType;
private string _roleClaimType = ClaimsIdentity.DefaultRoleClaimType;
private Dictionary<string, object> _instancePropertyBag;
private Dictionary<string, object> _propertyBag;
private IList<SecurityKey> _issuerSigningKeys;
private IList<string> _validIssuers;
private IList<string> _validTokenTypes;
Expand Down Expand Up @@ -77,7 +78,9 @@ protected ValidationParameters(ValidationParameters other)
LogTokenId = other.LogTokenId;
NameClaimType = other.NameClaimType;
NameClaimTypeRetriever = other.NameClaimTypeRetriever;
PropertyBag = other.PropertyBag;
foreach (var keyValue in other.PropertyBag)
PropertyBag[keyValue.Key] = keyValue.Value;

RefreshBeforeValidation = other.RefreshBeforeValidation;
RoleClaimType = other.RoleClaimType;
RoleClaimTypeRetriever = other.RoleClaimTypeRetriever;
Expand Down Expand Up @@ -282,7 +285,10 @@ public IssuerSigningKeyValidationDelegate IssuerSigningKeyValidator
/// Gets a <see cref="IDictionary{TKey, TValue}"/> that is unique to this instance.
/// Calling <see cref="Clone"/> will result in a new instance of this IDictionary.
/// </summary>
public IDictionary<string, object> InstancePropertyBag => _instancePropertyBag ??= new Dictionary<string, object>();
public IDictionary<string, object> InstancePropertyBag =>
_instancePropertyBag ??
Interlocked.CompareExchange(ref _instancePropertyBag, [], null) ??
_instancePropertyBag;

/// <summary>
/// Gets a value indicating if <see cref="Clone"/> was called to obtain this instance.
Expand Down Expand Up @@ -374,7 +380,9 @@ public string NameClaimType
/// Gets or sets the <see cref="IDictionary{TKey, TValue}"/> that contains a collection of custom key/value pairs.
/// This allows addition of parameters that could be used in custom token validation scenarios.
/// </summary>
public IDictionary<string, object> PropertyBag { get; }
public IDictionary<string, object> PropertyBag => _propertyBag ??
Interlocked.CompareExchange(ref _propertyBag, [], null) ??
_propertyBag;

/// <summary>
/// A boolean to control whether configuration should be refreshed before validating a token.
Expand Down
Loading

0 comments on commit 0f6c5a3

Please sign in to comment.