Search code examples
c#asp.netidentityserver4claims-based-identityasp.net-identity-3

How to make custom user claims be available in API requests


I have a solution consisting of:

  • ASP.NET Core 2.1 running IdentityServer4 on top of ASP.NET Identity Core.
  • ASP.NET Core 2.1 Web API set to use the IdentityServer as the authentication provider.
  • A React SPA web application using oidc-client javascript library.

When I create new users I set some custom claims that are saved in the AspNetUserClaims table which looks like this: enter image description here

Then, on my API project, inside a controller I want to get those user claims of the authenticated user.
I was expecting this.User.Claims to get me those, but instead that's returning the following, which seem to be claims related to the client app, not the user.

enter image description here

How can I access those custom user claims (address, location, tenant_role) from a controller inside the Web API project?
Bare in mind that the API project doesn't have access to the UserManager class or anything ASP.NET Identity Core related.


Solution

  • So, I order for my custom user claim to be available in every API request I had to do the following when setting up the ApiResource on the IdentityServer startup.

    //Config.cs
    public static IEnumerable<ApiResource> GetApiResources()
    {
        ApiResource apiResource = new ApiResource("api1", "DG Analytics Portal API")
        {
            UserClaims =
            {
                JwtClaimTypes.Name,
                JwtClaimTypes.Email,
                AnalyticsConstants.TenantRoleClaim // my custom claim key/name
            }
        };
    
        return new List<ApiResource>
        {
            apiResource
        };
    }
    

    This method is passed to the services.AddInMemoryApiResources (or whatever storage method you're using)

    IIdentityServerBuilder builder = services
                    .AddIdentityServer(options =>
                    {
                        options.Events.RaiseErrorEvents = true;
                        options.Events.RaiseInformationEvents = true;
                        options.Events.RaiseFailureEvents = true;
                        options.Events.RaiseSuccessEvents = true;
                    })
                    .AddInMemoryIdentityResources(Config.GetIdentityResources())
                    .AddInMemoryApiResources(Config.GetApiResources()) // here
                    .AddInMemoryClients(Config.GetClients())
                    .AddAspNetIdentity<ApplicationUser>();
    

    With that setup, whenever an API endpoint is hit, my custom TenantRole claim is present so I can simply do User.FindFirst(AnalyticsConstants.TenantRoleClaim) to get it.