2

I created a .NET Core 3.0 Angular project with Identity Server. I want to add claims and roles to my app.

My Identity Server is mostly out of the box with some simple route changes:

      services.AddIdentity<ApplicationUser, IdentityRole>()
              .AddDefaultTokenProviders()
              .AddEntityFrameworkStores<ApplicationDbContext>();

      services.AddIdentityServer(options =>
              {
                options.UserInteraction.LoginUrl = "/auth/login";
                options.UserInteraction.LogoutUrl = "/auth/logout";
              })
              .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

I currently add my a simple policy in startup.cs

services.AddAuthorization(options =>
      {
        options.AddPolicy("RequireAdministratorRole", policy =>
        {
          policy.RequireRole("Admin");
          policy.RequireClaim("CreateUser");
        });

      });

At the bottom of my Configure() method I call this method to add roles:

private async Task CreateUserRoles(IServiceProvider serviceProvider)
    {
      var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
      var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

      IdentityResult adminRoleResult;
      //Adding Admin Role
      var adminRoleCheck = await RoleManager.RoleExistsAsync("Admin");
      if (!adminRoleCheck)
      {
        //create the roles and seed them to the database
        adminRoleResult = await RoleManager.CreateAsync(new IdentityRole("Admin"));
        await RoleManager.AddClaimAsync(new IdentityRole("Admin"), new Claim("CreateUser", "Create User"));
      }

    }

In my register.cshtml.cs I've successfully set a role and a claim via:

var roleResult = await _userManager.AddToRoleAsync(user, "Admin");
var claimResult = await _userManager.AddClaimAsync(user, new Claim("CreateUser", "Create User"));

I've confirmed that the new user has that claim and role.

The client userinfo call returns correctly but when I look at the id_token I dont have those claims:

{
  "nbf": 1574787988,
  "exp": 1574788288,
  "iss": "https://localhost:5001",
  "aud": "MyAppSpa",
  "iat": 1574787988,
  "at_hash": "ndzldxAE3EiVzI4PeThNPQ",
  "s_hash": "dIqJXx372XhOESn1XYH36A",
  "sid": "VQLp--MHdoOoxXiVASWZ0g",
  "sub": "4a0450dd-fe4f-4b3d-ac12-3f70876183e1",
  "auth_time": 1574787983,
  "idp": "local",
  "amr": [
    "pwd"
  ]
}

According to oidc-client-js is not getting claims correctly from Identity Server 4, I should just need to include AlwaysIncludeUserClaimsInIdToken = true to the client configuration.

However, the template doesnt have a configuration. Its all under the hood.

Questions:

1) Will adding AlwaysIncludeUserClaimsInIdToken = true to the client fix my issue?

2) How do I add it given my current configuration?

JDillon522
  • 19,046
  • 15
  • 47
  • 81
  • The initial id_token only contains the `sub` claim (by design). Other information can be retrieved at the UserInfo endpoint, using the access token. But the problem is that you don't need the claims in the id_token, but in the access token. So instead of adding IdentityClaims, rather add ApiClaims. Please read my answer [here](https://stackoverflow.com/questions/53976553/identityserver4-role-based-authorization-for-web-api-with-asp-net-core-identity/54004765#54004765) for more explanation. –  Nov 26 '19 at 18:48

1 Answers1

1

Concern about the size of ID Token , by default the claims won't include in ID token .You can get the claims from userinfo endpoint with ID token(read from user.profile) . That is by design .

The new .net core 3.0 angular authentication template just configures IdentityServer to use template supported configuration , but the configuration is not fully customize compare to Identity server provided configuration ,such as AlwaysIncludeUserClaimsInIdToken . So the workaround is not use ApiAuthorization service, the full power of IdentityServer is still available to customize authentication to suit your needs.

Nan Yu
  • 26,101
  • 9
  • 68
  • 148
  • 1
    I was starting to come to the same conclusion that my main problem is using `ApiAuthorization` and letting IS do everything for me. I think I'll have to do it more deliberatly. Any idea offhand where the they define the `Client` object in the [repo](https://github.com/aspnet/AspNetCore)? I'd like to start with the exact config they are using and tweak it from there. – JDillon522 Nov 27 '19 at 13:10