Search code examples
asp.net-core-2.0identityserver4rolesclaims-based-identity

Missing Roles Claims in the ASP.NET Core 2 and IdentityServer4


I read https://leastprivilege.com/2017/11/15/missing-claims-in-the-asp-net-core-2-openid-connect-handler/ about mapping custom claims with this code line:

options.ClaimActions.MapUniqueJsonKey("website", "website");

I need to map roles and it works until I have just one role like "User".

options.ClaimActions.MapUniqueJsonKey("role", "role");

The problem is when I have more than one role like "User" and "Superadmin" That code line throws an exception:

InvalidCastException: Cannot cast Newtonsoft.Json.Linq.JArray to Newtonsoft.Json.Linq.JToken.

Anyone has any idea? Am i wrong something or it could be a bug?


Solution

  • There is a discussion of this issue here:

    https://github.com/aspnet/Security/issues/1383

    and in the same issue a potential solution to your problem with role:

    https://github.com/aspnet/Security/issues/1383#issuecomment-361505163 :

    oidcOptions.Events = new OpenIdConnectEvents()
    {
      OnUserInformationReceived = async context =>
      {
        // IDS4 returns multiple claim values as JSON arrays, which break the authentication handler
        if (context.User.TryGetValue(JwtClaimTypes.Role, out JToken role))
        {
          var claims = new List<Claim>();
          if (role.Type != JTokenType.Array) {
            claims.Add(new Claim(JwtClaimTypes.Role, (string)role));
          }
          else  {
            foreach (var r in role)
              claims.Add(new Claim(JwtClaimTypes.Role, (string)r));
          }
          var id = context.Principal.Identity as ClaimsIdentity;
          id.AddClaims(claims);
        }
      ...
    }