繁体   English   中英

如何从 .NET Core 6.0 中的 JWT 安全令牌读取自定义声明值

[英]How to read custom claim value from JWT security token in .NET Core 6.0

我无法从 Bearer JWT 令牌中读取令牌声明。

登录正常,HTTP 请求带有一个有效的 JWT 令牌到后端。 登录返回令牌。 这是我在服务器端的代码:

程序.cs

builder.Services.AddAuthentication(m => {
    //m.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    m.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    m.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(conf => {
        conf.RequireHttpsMetadata = false;
    conf.SaveToken = true;
    conf.TokenValidationParameters = new TokenValidationParameters
   {
       ValidateIssuer = true,
       ValidateAudience = true,
       ValidIssuer = Configuration["JWT-Issuer"],
       ValidAudience = Configuration["JWT-Issuer"],
       IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT-Key"])),
       ClockSkew = TimeSpan.Zero,
};
});

当我取消注释此行//m.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; postman 表示未经授权。 当它保持评论时,授权成功。

令牌在这里生成。

生成令牌方法:

private object GenerateJwtToken(string Id, string email, ApplicationUser appUser, string appUserRole, string FirstName)
        {
            List<Claim> claims = null;
            claims = new List<Claim> {
                new Claim(JwtRegisteredClaimNames.Email,email),
                new Claim(JwtRegisteredClaimNames.Jti, appUser.Id),
                new Claim("Role",appUserRole),
                new Claim("UserName",appUser.UserName),
                new Claim("TEMP", FirstName)
                }
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT-Key"]));
            var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expire = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JWT-Expiry"]));


            var token = new JwtSecurityToken(
                issuer: _configuration["JWT-Issuer"],
                audience: _configuration["JWT-Issuer"],
                claims: claims,
                expires: expire,
                signingCredentials: cred
                );


            return new JwtSecurityTokenHandler().WriteToken(token);

        }

当 JWT 不记名令牌传递给用[Authorize]装饰的 API 调用并使用调试器进行测试时,它表明像 TEMP这样的自定义声明不存在于User.Claims列表中。

从令牌中读取声明

  string Email = User.Claims.SingleOrDefault(x => x.Type.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")).Value;
  string FirstName= User.Claims.SingleOrDefault(x => x.Type.Equals("TEMP")).Value;

在这里,可以成功读取 email 但我无法从令牌中读取 FirstName。 事实上, User.Claims没有FirstName声明(我的意思是所有自定义声明都离开了 Registered JWT Default ClaimTypes),它只有默认的令牌参数,即电子邮件地址、ID、角色等。

我应该怎么办? 我应该为此目的创建自定义身份验证方案吗?

在 AddJwtBearer 内部,令牌处理程序完成了一些重新映射,其中声明被重命名,例如

email -> http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress

可以使用以下方法关闭此映射:

// Or set this flag to false
.AddJwtBearer(opt =>
{
    ...
    opt.MapInboundClaims = false;
});

或设置:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

实际映射可以在这里找到

但是,我不确定为什么找不到 TEMP 声明。 您在 controller 中的经过身份验证的用户中实际看到了什么声明? 在某些情况下,某些声明也被忽略。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM