5

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.

empz
  • 11,509
  • 16
  • 65
  • 106
  • Are you using access tokens? If so you could encode user claims into the token which should implicitly allow you to access them via `this.User.Claims`. Failing that you'll need to create a method of accessing the UserManager. – Chris Pickford Dec 10 '18 at 16:47
  • Yes, I'm using access token (via `Authorization: Bearer xxxx` header). Not sure how would I encode the claims into the token in IdentityServer. Any post/resource that explains how to do that? – empz Dec 10 '18 at 17:25

3 Answers3

3

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.

empz
  • 11,509
  • 16
  • 65
  • 106
0

You'll need to define identity resources and scopes a la:

http://docs.identityserver.io/en/latest/topics/resources.html

And then ensure that they are exposed by your IProfileService or IClaimsService implementation in your identity server:

http://docs.identityserver.io/en/latest/reference/profileservice.html

They claims can either be included in the tokens themselves or be access via the user info endpoint as needed - this is sensible if your claim data is particularly large (i.e. in the 1000s of characters).

mackie
  • 4,996
  • 1
  • 17
  • 17
  • I couldn't get this to work but I've found a much simpler solution. Not sure why nobody pointed that. See my answer. – empz Dec 10 '18 at 19:16
-1

You can use ClaimsPrincipal.FindFirst() to access your customized claims.

Doc: https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.findfirst?view=netcore-2.1

Example: User.FindFirst("your_claim_key").Value

wannadream
  • 1,669
  • 1
  • 12
  • 14
  • This does not work. The problem is not how to access them, the problem is that the claims are not present in the access token. There should be something on the IdentityServer4 side to tell it to include those claims in the token. – empz Dec 10 '18 at 17:27
  • I see. Here is a quick example: https://korzh.com/blogs/net-tricks/aspnet-identity-store-user-data-in-claims. – wannadream Dec 10 '18 at 18:12