Search code examples
asp.net-corejwtidentityserver4

In Identity Server 4, I have a User's identity but 0 Claims


I have an identity server, a JavaScript client, and an API. All have been configured so that Authentication and Authorization are working as expected. I am now attempting to load the current user by id (the sub claim) in my API. The problem is that the User.Claims enumeration is empty in all of my controllers.

I have decoded the bearer token I am sending with each request and have confirmed I have a sub claim. Is there some additional configuration needed in my API to receive these claims?

Decoded JWT

{
  "nbf": 1510436170,
  "exp": 1510439770,
  "iss": "https://localhost:44300",
  "aud": [
    "https://localhost:44300/resources",
    "mycustom.api"
  ],
  "client_id": "mycustom.web",
  "sub": "c92cc2bc-d063-49d6-a36e-f6340796df15",
  "auth_time": 1510435257,
  "idp": "local",
  "scope": [
    "openid",
    "profile",
    "mycustom.api"
  ],
  "amr": [
    "pwd"
  ]
}

API Configuration

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<BrewSwapDbContext>()
        .AddDefaultTokenProviders();

    services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = "https://localhost:44300";
            options.ApiName = "mycustom.api";
        });

    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseCors(builder =>
        builder.AllowAnyHeader()
        .AllowAnyMethod()
        .AllowAnyOrigin());

    app.UseStaticFiles();
    app.UseAuthentication();
    app.UseMvc();
}

Client Configuration

On the SPA client I am using angular-auth-oidc-client. Again, I am able to inspect the bearer token in each request and can see the sub claim I need. See the decoded JWT above.

let oidcConfig = new OpenIDImplicitFlowConfiguration()
oidcConfig.stsServer = "https://localhost:44300";
oidcConfig.redirect_url = "https://localhost:44302";
oidcConfig.client_id = 'mycustom.web';
oidcConfig.response_type = 'id_token token';
oidcConfig.scope = 'openid profile mycustom.api';
oidcConfig.post_logout_redirect_uri = "https://localhost:44302";
oidcConfig.start_checksession = false;
oidcConfig.silent_renew = true;
oidcConfig.silent_renew_offset_in_seconds = 0;
oidcConfig.startup_route = '/home';
oidcConfig.auto_userinfo = true;
oidcConfig.log_console_warning_active = true;
oidcConfig.log_console_debug_active = true;
oidcConfig.max_id_token_iat_offset_allowed_in_seconds = 10;
oidcConfig.storage = localStorage;

API Controller

public class ExampleController : Controller
{
    private readonly MyDbContext _context;

    public ExampleController(MyDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public IEnumerable<Example> GetExamples()
    {
        var test = User.Claims;
        return _context.Examples;
    }
}

You can see below that an identity was found... Identity found

but it has 0 claims. No claims


Solution

  • API Setup correction:

    This is the correct code for your ConfigureServices method.

    The AddIdentity is not needed since the information is provided by the claims that come from the IdentityServer4.

    public void ConfigureServices(IServiceCollection services)
    {
         services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "https://localhost:44300";
                options.ApiName = "mycustom.api";
            });
    
        services.AddMvc();
    }