Search code examples
asp.net-core-mvcidentityserver4openid-connect

Override default Identity Server 4 Client


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?


Solution

  • 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.