'JWT Bearer ASP.Net Core 3.1 User is blank on server

Today I've been attempting to bind JSON Web Token info to the HttpContext.User using the Microsoft.AspNetCore.Authentication.JwtBearer library.

The Problem: Every time I make a call to the server, I'm able to get into functions with the [Authorize] attribute, but the User object is completely blank. It would be nice to know who each user is.

My decoded JWT on the client-side: decoded_jwt

My client-side function to call an [Authorize] C# method on the server:

testAuth() {
    let token = localStorage.getItem("jwt");
    console.log(this.jwtHelper.decodeToken(token)); // Where I got the decoded JWT picture
    this.http.get(this.baseUrl + "Authentication/Test", {
      headers: new HttpHeaders({
        "Content-Type": "application/json",
        "Authentication": "Bearer " + token
      })
    }).subscribe(response => {
      console.log(response); // never happens
    }, err => {
      console.log(err); // always happens because User.Identity is null
    });
  }

The server method where User.Identity is always blank, but we are allowed through the [Authorize] attribute:

[HttpGet]
[Authorize]
public IActionResult Test()
{
    // User.Identity is always blank, so a 500 error is thrown because Name == null
    return Ok(HttpContext.User.Identity.Name);
}

Middleware pipeline: ConfigureServices() in Startup.cs:

services.AddControllers();

            // Enable CORS (cross origin requests) so other sites can send requests to the auth API
            services.AddCors();

            // JWT
            // Use JSON Web Tokens for auth
            services.AddAuthentication(opt => {
                opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = true,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = false,
                    IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration.GetValue<string>("JwtInfo:SecretKey"))),
                    ValidIssuer = Configuration.GetValue<string>("JwtInfo:ServerAddress", "http://localhost:44351/"), // Address that this project is running on
                    ValidAudience = Configuration.GetValue<string>("JwtInfo:ValidRecipients", "http://localhost:44364/") // Addresses of projects that are allowed to access this API
                };
            });

Configure() in Startup.cs:

app.UseHttpsRedirection();

            app.UseRouting();

            // Allow CORS (cross origin requests)
            // This must come before routing, authentication, and endpoints
            app.UseCors(option => option
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader());

            // Use JWT authentication
            app.UseAuthentication();
            app.UseAuthorization();

How do I correctly bind the JWT claims to the User's claims?

How am I getting through [Authorize] if the User is blank?

Your help is appreciated!



Solution 1:[1]

I had this issue with an application that was developed with Asp.net Core and angular. The solution that worked for me is to set in client side (angular) allowedDomains: ["ServerAdress:port"], in app.module

enter image description here

Solution 2:[2]

You need to use IHttpContextAccessor and register the dependency in the configure services method.

Step 1- register the dependency

services.AddHttpContextAccessor();

Step 2 - inject the dependency in the constructor of the controller or wherever you require

private readonly IHttpContextAccessor _httpContextAccessor;

public MyController(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}

Step 3 - use the code below to get user info var user = _httpContextAccessor.HttpContext.User.Identity;

From the ms documentation:

For other framework and custom components that require access to HttpContext, the recommended approach is to register a dependency using the built-in dependency injection container. The dependency injection container supplies the IHttpContextAccessor to any classes that declare it as a dependency in their constructors:

Here, is the official Microsoft documentation, please go through it to get more details:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Abdelwahid Oubaalla
Solution 2 Prateek Kumar Dalbehera