in src/Core/Authorization/AuthorizationResolver.cs [500:565]
public static Dictionary<string, string> GetProcessedUserClaims(HttpContext? context)
{
Dictionary<string, string> processedClaims = new();
if (context is null)
{
return processedClaims;
}
Dictionary<string, List<Claim>> userClaims = GetAllAuthenticatedUserClaims(context);
foreach ((string claimName, List<Claim> claimValues) in userClaims)
{
// Some identity providers (other than Entra ID) may emit a 'scope' claim as a JSON string array. dotnet will
// create claim objects for each value in the array. DAB will honor that format
// and processes the 'scope' claim objects as a JSON array serialized to a string.
if (claimValues.Count > 1)
{
switch (claimValues.First().ValueType)
{
case ClaimValueTypes.Boolean:
processedClaims.Add(claimName, value: JsonSerializer.Serialize(claimValues.Select(claim => bool.Parse(claim.Value))));
break;
case ClaimValueTypes.Integer:
case ClaimValueTypes.Integer32:
processedClaims.Add(claimName, value: JsonSerializer.Serialize(claimValues.Select(claim => int.Parse(claim.Value))));
break;
// Per Microsoft Docs: UInt32's CLS compliant alternative is Integer64
// https://learn.microsoft.com/dotnet/api/system.uint32#remarks
case ClaimValueTypes.UInteger32:
case ClaimValueTypes.Integer64:
processedClaims.Add(claimName, value: JsonSerializer.Serialize(claimValues.Select(claim => long.Parse(claim.Value))));
break;
// Per Microsoft Docs: UInt64's CLS compliant alternative is decimal
// https://learn.microsoft.com/dotnet/api/system.uint64#remarks
case ClaimValueTypes.UInteger64:
processedClaims.Add(claimName, value: JsonSerializer.Serialize(claimValues.Select(claim => decimal.Parse(claim.Value))));
break;
case ClaimValueTypes.Double:
processedClaims.Add(claimName, value: JsonSerializer.Serialize(claimValues.Select(claim => double.Parse(claim.Value))));
break;
case ClaimValueTypes.String:
case JsonClaimValueTypes.JsonNull:
case JsonClaimValueTypes.Json:
default:
string json = JsonSerializer.Serialize(claimValues.Select(claim => claim.Value));
processedClaims.Add(claimName, value: json);
break;
}
}
else
{
// Remaining claims will be collected as string scalar values.
// While Claim.ValueType may indicate the token value was not a string (int, bool),
// resolving the actual type here would be a breaking change because
// DAB has historically sent single instance claims as value type string.
// This block also accommodates Entra ID access tokens to avoid a breaking change because
// the 'scp' claim is a space delimited string which is not broken up into separate claim objects
// by dotnet. The Entra ID 'scp' claim should be passed to MSSQL's session context as-is.
// https://learn.microsoft.com/entra/identity-platform/access-token-claims-reference#payload-claims
processedClaims.Add(claimName, value: claimValues[0].Value);
}
}
return processedClaims;
}