Search code examples
asp.net-coreidentityserver4jwtasp.net-authorizationasp.net-core-5.0

User.Claims is empty after upgrading from ASP.NET Core 3.1 to ASP.NET 5.0


After upgrading from ASP.NET Core 3.1 to version 5, context.User.Claims is empty in

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)

in

public class MyRequirementHandler : AuthorizationHandler<MyRequirement>

I'm using the Authorization header with a bearer token with JWT. I can see that header being set correctly when looking at the HttpContext.Request.Headers but it doesn't seem to be parsed.

This is set up on a Grpc Service with the [Authorize] attribute.

With ASP.NET Core 3.1, it worked fine. I went through the official migration guide but their references regarding authorisation were only for Azure Active Directory.

I'm using IdentityServer4 which is hosted within that ASP.NET Core app as a middleware (app.UseIdentityServer();)

What did I forget to modify to get ASP.NET Core to parse the authorisation header correctly?

Update:

I checked it in more details and noticed that it's failing because it can't verify the audience (aud) - and yes on the newly created tokens the audience is missing (the old tokens had the audience). Also I noticed that a custom scope, which I was adding in

public override async Task GetProfileDataAsync(ProfileDataRequestContext context)

inside my custom

public class ProfileService : ProfileService<ApplicationUser>

is also missing after the update. This is how the IdentityServer is configured:

services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, AppIdentityDbContext>()
    .AddProfileService<ProfileService>()
    .AddInMemoryIdentityResources(AuthResources.GetIdentityResources())
    .AddInMemoryApiResources(AuthResources.GetApiResources())
    .AddInMemoryClients(TestClientsRequired
        ? ClientsForTesting.GetTestClients()
        : Clients.GetDefaultClients());

Solution

  • After figuring out that the issue might have been due to a missing audience (aud) I looked further and found Missing "aud" claim in access token - the answer was, to explicitly add the audience as a claim and also set the scope one more time, and it worked.

    For me this looks the following way:

    public static IEnumerable<ApiResource> GetApiResources()
    {
        yield return ApiResourceBuilder
            .IdentityServerJwt(MyWebApiResource)
            .AllowAllClients()
            .Build()
            .AddUserClaims()
            .AddScopes(); // <- this is new
    }
    
    private static T AddUserClaims<T>(this T resource)
        where T : Resource
    {
        resource.UserClaims.Add(Constants.CustomClaimTypes.MyRoles);
        resource.UserClaims.Add(JwtClaimTypes.Audience); // <- this is new
    
        return resource;
    }
    
    // this whole method is new ->
    private static T AddScopes<T>(this T resource)
        where T : ApiResource
    {
        resource.Scopes.Add(MyWebApiResource);
    
        return resource;
    }