User.Claims Is Empty In MVC Application

2020-06-16 02:53发布

问题:

I'm working on upgrading my .NET Core 2.2 MVC application to 3.0. In this application I'm authenticating to a controller using a JWT token. The token contains several claims, but when I try to access them through User.Claims the resulting list is always empty.

In my Startup.cs I have the authentication setup like so:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Code removed for clarity //

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = JwtManager.Issuer,
                    ValidAudience = "MyAudience",
                    IssuerSigningKey = "MySigningKey"
                };
            });
    }
}

In Core 2.2 I was able to access my claims using code similar to the following:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class MyController : Controller
{
    [HttpGet("MyController/Action")]
    public ActionResult<Aggregate[]> GetAction()
    {
        var username = User.FindFirstValue("MyUsernameClaim");
        if (username == null)
        {
            return Forbid();
        }       
        // Do Stuff //
    }
}

However, when I migrate the same code to Core 3.0, I authenticate properly, but I get no claims for the User object.

Did I miss a step in converting this to 3.0? Does User not get automatically populated with information anymore or something?

回答1:

It seems the user isn't authenticated at all.

With asp.net core 3.0 routing has changed to Endpoint routing. You can opt-out by setting EnableEndpointRouting = false.

But that seems not the case here. That means you'll have to include certain services when you use them, like authentication and authorization:

public void Configure(IApplicationBuilder app)
{
  ...

  app.UseStaticFiles();

  app.UseRouting();
  app.UseCors();

  app.UseAuthentication();
  app.UseAuthorization();

  app.UseEndpoints(endpoints => {
     endpoints.MapControllers();
  });

And most important, in that order. As documentated here: Migrate Startup.Configure.