【问题标题】:Cannot access JWT claims from ASP.NET HttpContext无法从 ASP.NET HttpContext 访问 JWT 声明
【发布时间】:2021-08-06 23:50:02
【问题描述】:

我试图从 ASP.NET Core 中的 Bearer 令牌访问用户的声明,但在处理程序中,HttpContext.User.Identity.Name 始终为空,Claims 集合为空。

令牌作为标头传递,如下所示:

授权:承载 eyJhbGci....

Startup.Configure 中,我在UseRouting 之后和UseEndpoints 之前调用UseAuthentication

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();
    app.UseAuthentication();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync(context.User.Identity.Name ?? "null");
        });
    });
}

Startup.ConfigureServices 我打电话给AddAuthenticationAddJwtBearer。我添加了一堆选项来尝试尽可能多地禁用验证,因为我现在只是尝试从令牌中读取值,但这没有帮助。

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => 
        {
            options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters {
                ValidateIssuer = false,
                ValidateIssuerSigningKey = false,
                ValidateAudience = false,
                ValidateActor = false,
                ValidateLifetime = false,
                ValidateTokenReplay = false,
            };
        }
    );
}

我的令牌是来自https://jwt.io/#debugger-io 的默认虚拟令牌,解码后看起来像这样:

{"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"John Doe","iat":1516239022}

为此我缺少什么?

【问题讨论】:

  • 你有没有设置断点或者使用F12开发者工具查看响应,遇到401错误?我检查了你的 JWT 配置和令牌,它会在我这边显示 401 错误,但是如果我使用 Issuer 和 SigningKey 生成 JWT 令牌(检查this screenshot),并更改 JWT 配置like this,我可以得到来自 HttpContext 的用户信息。所以,你可以试试这个方法。

标签: c# asp.net asp.net-core


【解决方案1】:

默认情况下,名称声明类型映射到 UniqueName,您需要更改它的映射。

.AddJwtBearer(o => o.TokenValidationParameters = new TokenValidationParameters
{
    NameClaimType = "name"
})

请参考这个问题: I can Authenticate with my JWT but my Name claim is not recognised in my ASP.NET Core application

【讨论】:

  • 这点很好,谢谢。但是,我只是没有任何声明(Claims 集合是空的,就像我提到的那样),所以这不仅仅是一个映射问题。
  • 但是 JWT 令牌包含一个名称声明 {"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"John Doe","iat":1516239022},所以我想你一定已经包含了它。您能否尝试添加名称声明并更新 NameClaimType 设置。
  • 是的,我添加了您提供的代码,但我的 Claims 集合仍然是空的(在 context.User.Claimscontext.User.Identity.Claims 上)。似乎 ASP.NET 给了我一个默认的空身份,并且不包括 JWT 令牌中的任何内容。
  • 能否更新问题并添加令牌生成代码?
  • 就像我在问题中提到的,我只是从jwt.io/#debugger-io 复制粘贴了一个虚拟的。
【解决方案2】:

这是我用来从 JWT 获取用户名的:

public class Helper
{
    /// <summary>
    /// Retrieve name of the user executing the request.
    /// </summary>
    /// <param name="user">User info.</param>
    /// <returns>User name.</returns>
    internal static string GetUserName(ClaimsPrincipal user)
    {
        return user.Claims
            .FirstOrDefault(c => c.Type == ClaimTypes.Name || c.Type == "name")
            .Value;
    }
}

然后这样称呼它:

Helper.GetUserName(HttpContext.User);

link to my repo 包含以上代码

【讨论】:

【解决方案3】:

试试这个:

 services
        .AddControllers(options =>
        {
            options.Filters.Add(new AuthorizeFilter());
        });

然后:

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

它必须有效。

【讨论】:

    【解决方案4】:

    你应该在UseAuthentication()中间件之后添加UseAuthorization()中间件

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

    你的 `Configure' 方法应该是这样的

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/", async context =>
            {
                await context.Response.WriteAsync(context.User.Identity.Name ?? "null");
            });
        });
    }
    

    【讨论】:

    • 这是我以前尝试过的,但没有运气。我不确定这个问题与授权有何关系。
    猜你喜欢
    • 1970-01-01
    • 2019-05-24
    • 2019-04-17
    • 2023-03-23
    • 2019-12-23
    • 2020-03-31
    • 2018-05-08
    • 2016-08-11
    • 2021-08-14
    相关资源
    最近更新 更多