Single-item-claim-array when using ClaimValueTypes.Json changing schema
See original GitHub issueHi folks,
Please see the previous two issues I filed eventually routing me here by the AspNetCore folks:
IdentityServer/IdentityServer4#3968 https://github.com/dotnet/aspnetcore/issues/18178
When sending over a JWT with an array claim with only one value, the claim in user.profile gets transformed to just a string. When an array with 2 values gets sent over in the JWT claim, user.profile sets it to an array with those 2 values.
This means that the schema changes depending on how many items are in the claim which is less than ideal and forces some special casing.
To Reproduce
Consider this code applied to a React + ASP.NET template with Individual User authentication/authorization. The snippet has IdentityServer send over the JWT claim as an array even if it only has one value in it:
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
// Get all the roles associated with this subject
IEnumerable<Claim> roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
// Put those roles into a list so we can serialize them after
IList<string> roles = new List<string>();
foreach (Claim roleClaim in roleClaims)
{
Debug.Assert(roleClaim.Type == JwtClaimTypes.Role);
roles.Add(roleClaim.Value);
}
// Serialize the roles into JSON
string rolesJson = JsonSerializer.Serialize(roles);
// Put the roles JSON into an actual Claim object
Claim claim = new Claim(JwtClaimTypes.Role, rolesJson, IdentityServerConstants.ClaimValueTypes.Json);
// Add the claim to the IssuedClaims which will eventually end up in the issued JWT
context.IssuedClaims.Add(claim);
return Task.CompletedTask;
}
The JWT that comes out on the other end does have an array with 1 value in it but user.profile transforms it into a string.
If you don’t want to actually create a role before testing this, just replace rolesJson
above with "[\"role1\"]"
.
From AuthorizeServices.js checking out user.profile where the claims end up on the client side:
I considered this as a bug because it overrides the explicitly defined preference of IdentityServer.
Further technical details
- ASP.NET Core version 3.1
.NET Core SDK (reflecting any global.json):
Version: 3.1.100
Commit: cd82f021f4
Runtime Environment:
OS Name: Windows
OS Version: 10.0.18362
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.1.100\
Host (useful for support): Version: 3.1.0 Commit: 65f04fb6db
.NET Core SDKs installed: 3.0.100 [C:\Program Files\dotnet\sdk] 3.1.100 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download
- The VSCode 1.41.1
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
@NickDarvey Yes, see this Stackoverflow answer
For reference my code was
Changed to
@a7md0, did you find a workaround for this?