4
votes

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

1
Did you include get claims from user info endpoint to true ?Muqeet Khan
app.UseOpenIdConnectAuthentication is obsolete. Where does getClaimsFromUserInfoEndpoint go now?Jonathan Eckman
Please share the client configuration and did you write any code on the IdentityServer4 side to populate the claims?aaronR
What happens when you add the [Authorize] attribute to the GetExample method? (Just to make sure authentication is set correctly.)aaronR
@aaronR good call. I found that it was attempting to redirect to login on my API, not id server. Comparing with master I found that services.AddIdentity() in API ConfigureServices was the culprit.Jonathan Eckman

1 Answers

3
votes

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();
}