JWT Bearer ASP.Net Core 3.1 用户在服务器上为空白

Posted

技术标签:

【中文标题】JWT Bearer ASP.Net Core 3.1 用户在服务器上为空白【英文标题】:JWT Bearer ASP.Net Core 3.1 User is blank on server 【发布时间】:2020-09-08 14:05:27 【问题描述】:

今天我一直在尝试使用 Microsoft.AspNetCore.Authentication.JwtBearer 库将 JSON Web Token 信息绑定到 HttpContext.User。

问题: 每次调用服务器时,我都可以使用 [Authorize] 属性进入函数,但 User 对象是完全空白的。 很高兴知道每个用户是谁。

我在客户端解码的 JWT:

我的客户端函数在服务器上调用 [Authorize] C# 方法:

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

User.Identity 始终为空的服务器方法,但我们可以通过 [Authorize] 属性:

[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);

中间件管道: Startup.cs 中的 ConfigureServices():

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

Startup.cs 中的Configure():

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

如何正确地将 JWT 声明绑定到用户声明?

如果用户为空白,我如何通过 [Authorize]?

感谢您的帮助!

【问题讨论】:

我认为你必须使用 httpcontext 访问器,从 3.1 开始我也无法通过 httprequest 对象读取 我认为您在AddJwtBearer 扩展方法中缺少Authority。我花了一些认真的故障排除来解决这个问题。 【参考方案1】:

需要使用IHttpContextAccessor,并在configure services方法中注册依赖。

第 1 步 - 注册依赖项

services.AddHttpContextAccessor();

第 2 步 - 在控制器的构造函数或您需要的任何地方注入依赖项

私有只读IHttpContextAccessor _httpContextAccessor;

public MyController(IHttpContextAccessor httpContextAccessor)

    _httpContextAccessor = httpContextAccessor;

第 3 步 - 使用以下代码获取用户信息 var user = _httpContextAccessor.HttpContext.User.Identity;

来自 ms 文档:

对于其他需要访问 HttpContext 的框架和自定义组件,推荐的方法是使用内置的依赖注入容器注册依赖。依赖注入容器将 IHttpContextAccessor 提供给在其构造函数中将其声明为依赖项的任何类:

这里是微软官方文档,请仔细阅读以获取更多详细信息:

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

【讨论】:

感谢您为我写这篇文章。不幸的是 _httpContextAccessor.HttpContext.User.Identity 仍然有 null 或空的声明/属性。【参考方案2】:

包含令牌的标头设置不正确。 应该是:

"Authorization": "Bearer " + token

代替“身份验证”:“承载”+令牌

【讨论】:

【参考方案3】:

我在使用 Asp.net Core 和 angular 开发的应用程序时遇到了这个问题。对我有用的解决方案是在 app.module 中设置客户端(角度)allowedDomains: ["ServerAdress:port"]

【讨论】:

以上是关于JWT Bearer ASP.Net Core 3.1 用户在服务器上为空白的主要内容,如果未能解决你的问题,请参考以下文章

JWT Bearer ASP.Net Core 3.1 用户在服务器上为空白

将 JWT Bearer Authentication Web API 与 Asp.Net Core 2.0 结合使用的问题

带有 JWT Bearer 令牌和 ASP.NET Core 2 WebApi 的 Azure AD 用户信息

ASP.NET Core MVC 向 Azure AD 验证用户,然后创建 JWT Bearer Token 以调用 Web API

ASP.net Core 2.0 AzureAd Bearer JWT-Token Auth 在验证签名时不会失败

每当我发送包含 Bearer 令牌的请求时,ASP.Net Core API 总是返回 401 未授权