Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
105e513
Added a test case to test presence of Signature in JsonWebToken. This…
saurabhsathe-ms May 1, 2025
b5c02e6
Included reference and implemented serialization logic
saurabhsathe-ms May 2, 2025
90d5667
Added a json parser that can parse the stringified claim without brea…
saurabhsathe-ms May 2, 2025
2a0c1b1
Found an ovverriden create token method for our requirement. Removing…
saurabhsathe-ms May 2, 2025
9b0c1bd
Added a check to ensure that the claimvalue is a valid json
saurabhsathe-ms May 2, 2025
b7a2280
Added logic to handle actor token from claims dictionary. Updated tes…
saurabhsathe-ms May 3, 2025
7b65a01
Updated JsonWebTokenHandlerCreateToken.cs to accomodate new changes. …
saurabhsathe-ms May 4, 2025
cd264f5
Removed the print statements and added header
saurabhsathe-ms May 4, 2025
a7b578d
"ActorTokenInClaimsDictionaryShouldBeProperlySerialized" now properly…
saurabhsathe-ms May 6, 2025
7a657e9
Added new testcases, added comments to testcase and modified existing…
saurabhsathe-ms May 6, 2025
04257cd
NIT repairs
saurabhsathe-ms May 6, 2025
d354200
Added one testcase to test MaxActorChainLength values.
saurabhsathe-ms May 6, 2025
ff64ddd
Removed Console.Writeline debugging statements
saurabhsathe-ms May 6, 2025
f66c4d0
Moved the Actor chain length parameter into a Configuration class tha…
saurabhsathe-ms May 7, 2025
5dc4a49
Made the configuration class public and static
saurabhsathe-ms May 7, 2025
ccb0688
Update src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.…
saurabhsathe-ms May 7, 2025
92a6285
Update src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.…
saurabhsathe-ms May 7, 2025
99f7fd5
Repaired testcases as per the suggestions on PR
saurabhsathe-ms May 7, 2025
4185264
Renamed JsonWebTokenConfiguration to JsonWebTokenHandlerConfiguration
saurabhsathe-ms May 7, 2025
8dcbdb3
Removed the comments on testcase
saurabhsathe-ms May 7, 2025
89cd0e4
Updated the configuration summary.
saurabhsathe-ms May 8, 2025
3ad51eb
Moved the MaxActorChainLength to SecurityTokenDescriptor
saurabhsathe-ms May 8, 2025
3f348bc
All test cases passed and introduced JWTclaimTypeName
saurabhsathe-ms May 8, 2025
787099b
Updated JsonWebToken.cs to now use SecurityTokenDescriptor.ActorClaim…
saurabhsathe-ms May 8, 2025
a92b6d6
Introduced a flag that we will be using to turn the feature on or off
saurabhsathe-ms May 9, 2025
36623ea
Cleaned the code and brought it all under one function
saurabhsathe-ms May 12, 2025
e3c25f9
Implemented non static version of ActorClaimName
saurabhsathe-ms May 13, 2025
e20d067
Removed console lines, Added a condition to check if the max actor ch…
saurabhsathe-ms May 13, 2025
d531454
moved actor chain depth to Security Token Descriptor
saurabhsathe-ms May 13, 2025
d79c61b
Updated validation parameters to validate JWT token upto a certain limit
saurabhsathe-ms May 15, 2025
f7de606
Removed old serialization. Added json object serialization and update…
saurabhsathe-ms May 17, 2025
f3c6ed2
Removed the changes to PublicUnshipped files for each frameworks
saurabhsathe-ms May 18, 2025
4185c6f
Added a delegate that users can use to validate their token
saurabhsathe-ms May 19, 2025
4c57aaf
NIT repairs round 1
saurabhsathe-ms May 19, 2025
a585112
Removed everything from TokenValidationParameters and the delegate
saurabhsathe-ms May 20, 2025
e6638ae
Revert "Removed everything from TokenValidationParameters and the del…
saurabhsathe-ms May 21, 2025
95db310
Renamed the switch and removed the validation code
saurabhsathe-ms May 21, 2025
9a1f6ed
Changed delegate name and added the tests to test our new function?
saurabhsathe-ms May 22, 2025
5e10aec
Added a testcase to test if act claim was properly deserialized
saurabhsathe-ms May 22, 2025
3b21635
Updated my local branch with dev
saurabhsathe-ms May 22, 2025
a7398a8
Created delegate and added testcases
saurabhsathe-ms May 23, 2025
a8efcb8
Fixed one bug in Deserialization. Divided all the testcases in 2 part…
saurabhsathe-ms May 23, 2025
4d2770f
NIT repairs, renamed some fields and adjusted some default values as …
saurabhsathe-ms May 23, 2025
bd78d2e
Some more NIT repairs
saurabhsathe-ms May 23, 2025
9503403
Merge branch 'dev' into ssathe/serializeClaimsIdentity
saurabhsathe-ms May 23, 2025
78cc3bc
Updated the code custom actclaimretrievervalidator call with token va…
saurabhsathe-ms May 27, 2025
bbb2f02
Updated summary for our new AppContextSwitch
saurabhsathe-ms May 27, 2025
e7952d1
Removed App context switch replaced it with request based property
saurabhsathe-ms Jun 4, 2025
e3e47ee
NIT updates
saurabhsathe-ms Jun 4, 2025
06b5820
Merge branch 'dev' into ssathe/serializeClaimsIdentity
saurabhsathe-ms Jun 4, 2025
1dfda65
Removed the use of flag during serialization and everything is working
saurabhsathe-ms Jun 7, 2025
6caaae5
Removed the flag from SecurityTokenDescriptor altogether
saurabhsathe-ms Jun 7, 2025
7cbe282
Removed the flag from token validation parameters too. Also added one…
saurabhsathe-ms Jun 7, 2025
8eede12
Latest pull
saurabhsathe-ms Jun 16, 2025
e5ce2bc
Merge branch 'ssathe/serializeClaimsIdentityWithoutFlag' into ssathe/…
saurabhsathe-ms Jun 16, 2025
e28773c
Resolved feedback!
saurabhsathe-ms Jun 19, 2025
badf08a
Change HasKey with TryGetValue for perf improvement
saurabhsathe-ms Jun 19, 2025
2c23923
Merge branch 'dev' into ssathe/serializeClaimsIdentity
saurabhsathe-ms Jun 20, 2025
2ab6ef6
Merge with main
saurabhsathe-ms Sep 30, 2025
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 @@ -668,11 +668,16 @@ internal static void WriteJwsPayload(
// Duplicates are resolved according to the following priority:
// SecurityTokenDescriptor.{Audience/Audiences, Issuer, Expires, IssuedAt, NotBefore}, SecurityTokenDescriptor.Claims, SecurityTokenDescriptor.Subject.Claims
// SecurityTokenDescriptor.Claims are KeyValuePairs<string,object>, whereas SecurityTokenDescriptor.Subject.Claims are System.Security.Claims.Claim and are processed differently.

bool isActorFound = false;
if (tokenDescriptor.Claims != null && tokenDescriptor.Claims.Count > 0)
{
foreach (KeyValuePair<string, object> kvp in tokenDescriptor.Claims)
{
if (kvp.Key.Equals(tokenDescriptor.ActorClaimType, StringComparison.Ordinal))
Copy link
Contributor

@brentschmaltz brentschmaltz Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the logic for duplicate claims, we should write out the 'actor' claim, not sure why we continue.

         // Duplicates are resolved according to the following priority:
         // SecurityTokenDescriptor.{Audience/Audiences, Issuer, Expires, IssuedAt, NotBefore}, SecurityTokenDescriptor.Claims, SecurityTokenDescriptor.Subject.Claims
         // SecurityTokenDescriptor.Claims are KeyValuePairs<string,object>, whereas SecurityTokenDescriptor.Subject.Claims are System.Security.Claims.Claim and are processed differently.

{
isActorFound = true;
continue;
}
if (!descriptorClaimsAudienceChecked && kvp.Key.Equals(JwtRegisteredClaimNames.Aud, StringComparison.Ordinal))
{
descriptorClaimsAudienceChecked = true;
Expand Down Expand Up @@ -754,6 +759,8 @@ internal static void WriteJwsPayload(
JsonPrimitives.WriteObject(ref writer, kvp.Key, kvp.Value);
}
}
if (isActorFound || tokenDescriptor.Subject?.Actor != null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be: !isActorFound

WriteActorToken(writer, tokenDescriptor, setDefaultTimesOnTokenCreation, tokenLifetimeInMinutes);

AddSubjectClaims(ref writer, tokenDescriptor, audienceSet, issuerSet, ref expSet, ref iatSet, ref nbfSet);

Expand Down Expand Up @@ -1071,6 +1078,74 @@ internal static byte[] WriteJweHeader(SecurityTokenDescriptor tokenDescriptor)
}
}
}
internal static void WriteActorToken(
Utf8JsonWriter writer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is important to pass the writer using the 'ref' keyword.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do this thank you for your review @brentschmaltz

SecurityTokenDescriptor tokenDescriptor,
bool setDefaultTimesOnTokenCreation,
int tokenLifetimeInMinutes)
{
if (tokenDescriptor == null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tokenDescriptor should never be null here, you can check for null, but don't throw, just return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, will do this!

throw new ArgumentNullException(nameof(tokenDescriptor));

var actorTokenDescriptor = CreateActorTokenDescriptor(tokenDescriptor);
if (actorTokenDescriptor == null || actorTokenDescriptor.Subject == null)
return;

writer.WritePropertyName(tokenDescriptor.ActorClaimType);
WriteJwsPayload(ref writer, actorTokenDescriptor, setDefaultTimesOnTokenCreation, tokenLifetimeInMinutes);
Copy link
Contributor

@brentschmaltz brentschmaltz Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simply this method by just passing the ClaimsIdentity, and the writing the claims into JSON.
Assume that only the claims in the ClaimsIdentity need to be added to the JSON.

The parameters to this method could be.

internal static void WriteActorToken(
            ref Utf8JsonWriter writer,
            string claimName,
            ClaimsIdentity claimsIdentity)

}

private static void ValidateActorChainDepth(SecurityTokenDescriptor tokenDescriptor)
{
if (tokenDescriptor.ActorChainDepth >= tokenDescriptor.MaxActorChainLength)
{
throw LogHelper.LogExceptionMessage(
new SecurityTokenException(LogHelper.FormatInvariant(
LogMessages.IDX14313,
LogHelper.MarkAsNonPII(tokenDescriptor.ActorChainDepth),
LogHelper.MarkAsNonPII(tokenDescriptor.MaxActorChainLength))));
}
}

private static SecurityTokenDescriptor CreateActorTokenDescriptor(SecurityTokenDescriptor tokenDescriptor)
{
SecurityTokenDescriptor actorTokenDescriptor = null;

if (tokenDescriptor.Claims?.TryGetValue(tokenDescriptor.ActorClaimType, out object actorValue) == true)
{
if (actorValue is not ClaimsIdentity actor)
{
throw LogHelper.LogExceptionMessage(new SecurityTokenException(
LogHelper.FormatInvariant(
LogMessages.IDX14315,
LogHelper.MarkAsNonPII(tokenDescriptor.ActorClaimType),
LogHelper.MarkAsNonPII(actorValue?.GetType().ToString() ?? "null"))));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LogHelper.MarkAsNonPII(actorValue?.GetType().ToString() ?? "null"))));
LogHelper.MarkAsNonPII(actorValue?.GetType().FullName ?? "null"))));

}

actorTokenDescriptor = new SecurityTokenDescriptor
{
Subject = actor,
};

}
// Then check for actor in subject
else if (tokenDescriptor.Subject?.Actor != null)
{
actorTokenDescriptor = new SecurityTokenDescriptor
{
Subject = tokenDescriptor.Subject.Actor,
};
}
if (actorTokenDescriptor != null)
{
ValidateActorChainDepth(tokenDescriptor);
actorTokenDescriptor.MaxActorChainLength = tokenDescriptor.MaxActorChainLength;
actorTokenDescriptor.ActorClaimType = tokenDescriptor.ActorClaimType;
actorTokenDescriptor.ActorChainDepth = tokenDescriptor.ActorChainDepth + 1;
}

return actorTokenDescriptor;
}

internal static byte[] CompressToken(byte[] utf8Bytes, string compressionAlgorithm)
{
Expand Down
153 changes: 136 additions & 17 deletions src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -212,8 +213,8 @@ protected virtual ClaimsIdentity CreateClaimsIdentity(JsonWebToken jwtToken, Tok

private ClaimsIdentity CreateClaimsIdentityWithMapping(JsonWebToken jwtToken, TokenValidationParameters validationParameters, string issuer)
{
_ = validationParameters ?? throw LogHelper.LogArgumentNullException(nameof(validationParameters));

_ = validationParameters ?? throw LogHelper.LogArgumentNullException(nameof(validationParameters));
ClaimsIdentity identity = validationParameters.CreateClaimsIdentity(jwtToken, issuer);
foreach (Claim jwtClaim in jwtToken.Claims)
{
Expand All @@ -222,19 +223,14 @@ private ClaimsIdentity CreateClaimsIdentityWithMapping(JsonWebToken jwtToken, To
if (!wasMapped)
claimType = jwtClaim.Type;

if (claimType == ClaimTypes.Actor)
if (claimType.Equals(validationParameters.ActorClaimType) || claimType.Equals("actort"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use JwtRegisteredClaimNames.Actort instead of literal.

{
if (identity.Actor != null)
throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(
LogMessages.IDX14112,
LogHelper.MarkAsNonPII(JwtRegisteredClaimNames.Actort),
LogHelper.MarkAsNonPII(claimType),
jwtClaim.Value)));

if (CanReadToken(jwtClaim.Value))
{
JsonWebToken actor = ReadToken(jwtClaim.Value) as JsonWebToken;
identity.Actor = CreateClaimsIdentity(actor, validationParameters);
}
identity.Actor = CreateClaimsIdentityActor(jwtToken, jwtClaim.Value, validationParameters, claimType.Equals(validationParameters.ActorClaimType));
}

if (wasMapped)
Expand Down Expand Up @@ -287,16 +283,11 @@ private ClaimsIdentity CreateClaimsIdentityPrivate(JsonWebToken jwtToken, TokenV
foreach (Claim jwtClaim in jwtToken.Claims)
{
string claimType = jwtClaim.Type;
if (claimType == ClaimTypes.Actor)
if (claimType == validationParameters.ActorClaimType || claimType.Equals("actort"))
{
if (identity.Actor != null)
throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX14112, LogHelper.MarkAsNonPII(JwtRegisteredClaimNames.Actort), jwtClaim.Value)));

if (CanReadToken(jwtClaim.Value))
{
JsonWebToken actor = ReadToken(jwtClaim.Value) as JsonWebToken;
identity.Actor = CreateClaimsIdentity(actor, validationParameters, issuer);
}
throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX14112, LogHelper.MarkAsNonPII(claimType), jwtClaim.Value)));
identity.Actor = CreateClaimsIdentityActor(jwtToken, jwtClaim.Value, validationParameters, claimType.Equals(validationParameters.ActorClaimType));
}

if (jwtClaim.Properties.Count == 0)
Expand Down Expand Up @@ -621,5 +612,133 @@ private static TokenValidationResult ReadToken(string token, TokenValidationPara
IsValid = true
};
}

/// <summary>
/// Creates a ClaimsIdentity from an actor claim string.
/// </summary>
/// <param name="jwtToken"></param>
/// <param name="actorString">The actor claim string.</param>
/// <param name="tokenValidationParameters">The token validation parameters.</param>
/// <param name="isStandardAct">This tells us if we want to deserialize it as a JWT or Json Object. If this is set to true then we deserialize as JsonObject else as JWT </param>
/// <returns>A ClaimsIdentity representing the actor.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="actorString"/> or <paramref name="tokenValidationParameters"/> is null.</exception>
private ClaimsIdentity CreateClaimsIdentityActor(
JsonWebToken jwtToken,
string actorString,
TokenValidationParameters tokenValidationParameters,
bool isStandardAct = false)
{
if (string.IsNullOrEmpty(actorString))
throw LogHelper.LogArgumentNullException(nameof(actorString));

if (tokenValidationParameters == null)
throw LogHelper.LogArgumentNullException(nameof(tokenValidationParameters));

if (isStandardAct)
{
if (jwtToken.TryGetPayloadValue<JsonElement>(tokenValidationParameters.ActorClaimType, out JsonElement actClaim))
{
if (tokenValidationParameters.ActClaimRetrieverDelegate != null)
{
try
{
return tokenValidationParameters.ActClaimRetrieverDelegate(actClaim, tokenValidationParameters);
}
catch (Exception ex)
{
throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(LogHelper.FormatInvariant(
LogMessages.IDX14314,
LogHelper.MarkAsNonPII(ex.ToString()))));
}
}
else
{
return CreateActorClaimsIdentityFromJsonElement(actClaim, tokenValidationParameters);
}
}

}
else
{
if (CanReadToken(actorString))
{
JsonWebToken actor = ReadToken(actorString) as JsonWebToken;
return CreateClaimsIdentity(actor, tokenValidationParameters);
}
}

return null;
}

/// <summary>
/// Creates a ClaimsIdentity from a JsonElement that represents an actor token.
/// </summary>
/// <param name="jsonElement">The JsonElement containing actor claims.</param>
/// <param name="tokenValidationParameters">These parameters have details like nested actor chain length and max permissible actor length</param>
/// <param name="issuer">The issuer for the claims.</param>
/// <returns>A ClaimsIdentity containing claims from the JsonElement.</returns>
public static ClaimsIdentity CreateActorClaimsIdentityFromJsonElement(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be private.

JsonElement jsonElement,
TokenValidationParameters tokenValidationParameters,
string issuer = null)
{
if (tokenValidationParameters == null)
throw LogHelper.LogArgumentNullException(nameof(tokenValidationParameters));

if (tokenValidationParameters.ActorChainDepth >= tokenValidationParameters.MaxActorChainLength)
{
throw LogHelper.LogExceptionMessage(
new SecurityTokenException(LogHelper.FormatInvariant(
LogMessages.IDX14313,
LogHelper.MarkAsNonPII(tokenValidationParameters.ActorChainDepth),
LogHelper.MarkAsNonPII(tokenValidationParameters.MaxActorChainLength))));
}

if (jsonElement.ValueKind != JsonValueKind.Object)
throw LogHelper.LogExceptionMessage(new ArgumentException("Actor token must be a JSON object"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use IDX error message?


// Use CaseSensitiveClaimsIdentity for consistent behavior with the rest of the library
var identity = new CaseSensitiveClaimsIdentity();

issuer = issuer ?? ClaimsIdentity.DefaultIssuer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
issuer = issuer ?? ClaimsIdentity.DefaultIssuer;
issuer ??= ClaimsIdentity.DefaultIssuer;


foreach (var property in jsonElement.EnumerateObject())
{
string claimType = property.Name;
JsonElement value = property.Value;

// Special handling for nested actor claim
if (claimType == tokenValidationParameters.ActorClaimType)
{
if (value.ValueKind == JsonValueKind.Object)
{
tokenValidationParameters.ActorChainDepth++;
// Recursively create nested actor identity
identity.Actor = CreateActorClaimsIdentityFromJsonElement(
value, tokenValidationParameters, issuer);
}
continue;
}

// For all other claims, create and add them
if (value.ValueKind == JsonValueKind.Array)
{
foreach (JsonElement element in value.EnumerateArray())
{
var claim = JsonClaimSet.CreateClaimFromJsonElement(claimType, issuer, element);
if (claim != null)
identity.AddClaim(claim);
}
}
else
{
var claim = JsonClaimSet.CreateClaimFromJsonElement(claimType, issuer, value);
if (claim != null)
identity.AddClaim(claim);
}
}

return identity;
}
}
}
3 changes: 3 additions & 0 deletions src/Microsoft.IdentityModel.JsonWebTokens/LogMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@ internal static class LogMessages
internal const string IDX14310 = "IDX14310: JWE authentication tag is missing.";
internal const string IDX14311 = "IDX14311: Unable to decode the authentication tag as a Base64Url encoded string.";
internal const string IDX14312 = "IDX14312: Unable to decode the cipher text as a Base64Url encoded string.";
internal const string IDX14313 = "IDX14313: Unable to serialize/deserialize act claim. Maximum actor token depth reached. Current nesting depth is {0} while max depth set is {1}";
internal const string IDX14314 = "IDX14314: Unable to deserialize act claim. Exception faced while using custom delegate to deserialize act claim. Nested exception is :{0}";
internal const string IDX14315 = "IDX14315: Encountered an exception while processing the actor claim. Actor claim {0} is not a claims identity. It is of type {1}.";
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\..\build\common.props" />

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.DecryptTokenWithConfigurationAsync(Microsoft.IdentityModel.JsonWebTokens.JsonWebToken jwtToken, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<string>
static Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.CreateActorClaimsIdentityFromJsonElement(System.Text.Json.JsonElement jsonElement, Microsoft.IdentityModel.Tokens.TokenValidationParameters tokenValidationParameters, string issuer = null) -> System.Security.Claims.ClaimsIdentity
Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.DecryptTokenWithConfigurationAsync(Microsoft.IdentityModel.JsonWebTokens.JsonWebToken jwtToken, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<string>
9 changes: 9 additions & 0 deletions src/Microsoft.IdentityModel.Tokens/Delegates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;

Expand Down Expand Up @@ -194,4 +195,12 @@ namespace Microsoft.IdentityModel.Tokens
/// <param name="claimValue">The claim value that was read and parsed from the reader.</param>
/// <returns>True, if the claim value was read successfully; false otherwise.</returns>
public delegate bool TryReadJwtClaim(ref Utf8JsonReader reader, JwtSegmentType jwtSegmentType, string claimName, out object claimValue);

/// <summary>
/// Delegate to validate the 'act' claim and create actor's ClaimsIdentity.
/// </summary>
/// <param name="actClaim">The JSON element representing the 'act' claim.</param>
/// <param name="tokenValidationParameters"> Opitonal validation parameters if needed</param>
/// <returns>A ClaimsIdentity representing the actor.</returns>
public delegate ClaimsIdentity ActClaimRetrieverDelegate(JsonElement actClaim, TokenValidationParameters tokenValidationParameters = null);
}
Loading
Loading