Skip to content

Commit

Permalink
Updated documentation for the new validation model and restructured i…
Browse files Browse the repository at this point in the history
…nternals (#3056)

* Removed static stack frames and replaced with the simplified approach of GetCurrentStackFrame() and AddCurrentStackFrame()

* Updated IssuerValidationSource to be extensible. Extracted validated fields onto their own files and made the structures read-only.

* Updated documentation

* Added nullability annotations to ValidationParameters. Enabled setting IList values from two-part constructors.

* Handle case where ValidateActor is true, there is an actor token, but no ActorValidationParameters are provided.

* Updated documentation, added missing interfaces and methods required once the classes/structures are made public.

* Added missing documentation around validation errors

(cherry picked from commit 07a105f)

* Added CLSCompliant flag to Log methods to address the build issue until the ILogger compliance can be resolved.

(cherry picked from commit af561ef)

* Moved signature error back to internal after merging from the new validation model feature branch.

* Cache exceptions from ValidationErrors

* Added log level checks for log methods in ValidatedToken and ValidationError

* Updated comment for issuer validation source for clarity

* Removed use of "this" in constructors.

* Updated documentation based on PR feedback

* Removed primary constructor from ValidatedToken in favour of clarity with a regular constructor with validations

* Overridden ToString method for validation objects.

* Added default value for the cancellation token on the entry points for the new validation model
  • Loading branch information
iNinja authored Jan 20, 2025
1 parent 0108a96 commit 658604a
Show file tree
Hide file tree
Showing 45 changed files with 1,153 additions and 521 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(Microsoft.IdentityModel.Tokens.SecurityToken token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(string token, Microsoft.IdentityModel.Tokens.ValidationParameters validationParameters, Microsoft.IdentityModel.Tokens.CallContext callContext, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.IdentityModel.Tokens.ValidationResult<Microsoft.IdentityModel.Tokens.ValidatedToken>>
Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler._telemetryClient -> Microsoft.IdentityModel.Telemetry.ITelemetryClient
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
Expand All @@ -6,4 +8,3 @@ static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.WriteJweHeader(
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.WriteJweHeader(Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor tokenDescriptor) -> byte[]
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.WriteJwsHeader(ref System.Text.Json.Utf8JsonWriter writer, Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor tokenDescriptor) -> void
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.WriteJwsHeader(ref System.Text.Json.Utf8JsonWriter writer, Microsoft.IdentityModel.Tokens.SigningCredentials signingCredentials, Microsoft.IdentityModel.Tokens.EncryptingCredentials encryptingCredentials, System.Collections.Generic.IDictionary<string, object> jweHeaderClaims, System.Collections.Generic.IDictionary<string, object> jwsHeaderClaims, string tokenType, bool includeKeyIdInHeader) -> void
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.StackFrames.IssuerValidatorThrew -> System.Diagnostics.StackFrame
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.IdentityModel.Logging;
Expand Down Expand Up @@ -31,49 +30,42 @@ internal ValidationResult<string> DecryptToken(
{
if (jwtToken == null)
{
StackFrame tokenNullStackFrame = StackFrames.DecryptionTokenNull ??= new StackFrame(true);
return ValidationError.NullParameter(
nameof(jwtToken),
tokenNullStackFrame);
ValidationError.GetCurrentStackFrame());
}

if (validationParameters == null)
{
StackFrame validationParametersNullStackFrame = StackFrames.DecryptionValidationParametersNull ??= new StackFrame(true);
return ValidationError.NullParameter(
nameof(validationParameters),
validationParametersNullStackFrame);
ValidationError.GetCurrentStackFrame());
}

if (string.IsNullOrEmpty(jwtToken.Enc))
{
StackFrame headerMissingStackFrame = StackFrames.DecryptionHeaderMissing ??= new StackFrame(true);
return new ValidationError(
new MessageDetail(TokenLogMessages.IDX10612),
ValidationFailureType.TokenDecryptionFailed,
typeof(SecurityTokenException),
headerMissingStackFrame);
ValidationError.GetCurrentStackFrame());
}

(IList<SecurityKey>? contentEncryptionKeys, ValidationError? validationError) result =
GetContentEncryptionKeys(jwtToken, validationParameters, configuration, callContext);

if (result.validationError != null)
{
StackFrame decryptionGetKeysStackFrame = StackFrames.DecryptionGetEncryptionKeys ??= new StackFrame(true);
return result.validationError.AddStackFrame(decryptionGetKeysStackFrame);
}
return result.validationError.AddCurrentStackFrame();

if (result.contentEncryptionKeys == null || result.contentEncryptionKeys.Count == 0)
{
StackFrame noKeysTriedStackFrame = StackFrames.DecryptionNoKeysTried ??= new StackFrame(true);
return new ValidationError(
new MessageDetail(
TokenLogMessages.IDX10609,
LogHelper.MarkAsSecurityArtifact(jwtToken, JwtTokenUtilities.SafeLogJwtToken)),
ValidationFailureType.TokenDecryptionFailed,
typeof(SecurityTokenDecryptionFailedException),
noKeysTriedStackFrame);
ValidationError.GetCurrentStackFrame());
}

return JwtTokenUtilities.DecryptJwtToken(
Expand Down Expand Up @@ -211,7 +203,6 @@ internal ValidationResult<string> DecryptToken(
return (unwrappedKeys, null);
else
{
StackFrame decryptionKeyUnwrapFailedStackFrame = StackFrames.DecryptionKeyUnwrapFailed ??= new StackFrame(true);
ValidationError validationError = new(
new MessageDetail(
TokenLogMessages.IDX10618,
Expand All @@ -220,7 +211,7 @@ internal ValidationResult<string> DecryptToken(
LogHelper.MarkAsSecurityArtifact(jwtToken, JwtTokenUtilities.SafeLogJwtToken)),
ValidationFailureType.TokenDecryptionFailed,
typeof(SecurityTokenKeyWrapException),
decryptionKeyUnwrapFailedStackFrame);
ValidationError.GetCurrentStackFrame());

return (null, validationError);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics;
using Microsoft.IdentityModel.Tokens;

#nullable enable
Expand All @@ -28,10 +27,9 @@ internal static ValidationResult<SecurityToken> ReadToken(
{
if (string.IsNullOrEmpty(token))
{
StackFrame nullTokenStackFrame = StackFrames.ReadTokenNullOrEmpty ?? new StackFrame(true);
return ValidationError.NullParameter(
nameof(token),
nullTokenStackFrame);
ValidationError.GetCurrentStackFrame());
}

try
Expand All @@ -43,12 +41,11 @@ internal static ValidationResult<SecurityToken> ReadToken(
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
StackFrame malformedTokenStackFrame = StackFrames.ReadTokenMalformed ?? new StackFrame(true);
return new ValidationError(
new MessageDetail(LogMessages.IDX14107),
ValidationFailureType.TokenReadingFailed,
typeof(SecurityTokenMalformedException),
malformedTokenStackFrame,
ValidationError.GetCurrentStackFrame(),
ex);
}
}
Expand Down
Loading

0 comments on commit 658604a

Please sign in to comment.