sakura-bloom
sakura-bloom

Reputation: 4594

IdentityServer 4 - user roles missing

In my Client I have the following set up.

services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        //options.DefaultSignInScheme = "Cookies",
    })
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.Authority = "...";
        options.ClientId = "...";
        options.SaveTokens = true;
        options.ClientSecret = "secret";
        options.SignInScheme = "Cookies";
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("roles");
        options.ResponseType = "code id_token";
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Events = new OpenIdConnectEvents()
        {
            OnTokenValidated = tokenValidatedContext =>
            {
                var identity = tokenValidatedContext.Principal.Identity
                    as ClaimsIdentity;

                var targetClaims = identity.Claims.Where(z =>
                    new[] {"sub"}.Contains(z.Type));

                var newClaimsIdentity = new ClaimsIdentity(
                    targetClaims,
                    identity.AuthenticationType,
                    "given_name",
                    "role");

                tokenValidatedContext.Principal =
                    new ClaimsPrincipal(newClaimsIdentity);

                return Task.CompletedTask;
            },
            OnUserInformationReceived = userInformationReceivedContext =>
            {
                return Task.FromResult(0);
            }
        };
    });

My client at the level of IdentityServer is defined as follows.

new Client()
{
    ClientName = "My App",
    ClientId = "mymagicapp",
    AllowedGrantTypes = GrantTypes.Hybrid,
    RedirectUris = new List<string>()
    {
        "https://..."
    },
    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "roles"
    },
    ClientSecrets = { new Secret("secret".Sha256()) },
    PostLogoutRedirectUris =
    {
        "https://..."
    }
}

The new "roles" scope is added as per below.

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new List<IdentityResource>()
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResource("roles", "Your role(s)", new List<string>(){"role"})
    };
}

A user is defined as follows.

new TestUser()
{
    SubjectId = "abcdef",
    Username = "Jane",
    Password = "password",
    Claims = new List<Claim>()
    {
        new Claim("given_name", "Jane"),
        new Claim("family_name", "Doe"),
        new Claim("role", "FreeUser")
    }
}

After logging in to my MVC client, in the Controller the User.Claims object does not contain role claim.

However, in the OnUserInformationReceived the userInformationReceivedContext's User object does contain the role claim.

What am I missing?

Upvotes: 2

Views: 3916

Answers (1)

sakura-bloom
sakura-bloom

Reputation: 4594

Based on

the solution was to add options.ClaimActions.MapJsonKey("role", "role"); inside .AddOpenIdConnect(options => ...)

From the second link:

2.0 no longer adds all possible information from the user-info endpoint, it was causing major cookie bloat leading to login issues. There is now a system called ClaimActions where you can select which elements you want to map from the user info doc to claims. See OpenIdConnectOptions.ClaimActions.

Upvotes: 2

Related Questions