8
votes

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. enter image description here

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

1
Can you confirm that the user is authenticated? I can't see from the image but User.Identity.IsAuthenticated seems false. If so, then this may have to do with the AuthenticationScheme.Ruard van Elburg
How did you configure routing? Did you add UseRouting, UseAuthentication and UseAuthorization in that order before UseEndpoints? Can you show that piece of code?Ruard van Elburg
@RuardvanElburg I moved UseEndpoints to the end of the Configure method and that fixed things. Holy cow, I can't believe something so simple like that has cost me an embarrassing amount of time. If you want to post that as the answer I'll accept it.Chris Stillwell

1 Answers

2
votes

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.