简体   繁体   English

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

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

I can't read token claims from Bearer JWT token.我无法从 Bearer JWT 令牌中读取令牌声明。

Login is working, the HTTP request comes with a valid JWT token to the backend.登录正常,HTTP 请求带有一个有效的 JWT 令牌到后端。 Login returns the token.登录返回令牌。 Here is my code on server side:这是我在服务器端的代码:

Program.cs程序.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,
};
});

When I uncomment this line //m.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;当我取消注释此行//m.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; postman says unauthorized. postman 表示未经授权。 When it is kept commented, authorization succeeds.当它保持评论时,授权成功。

Token is generated here.令牌在这里生成。

GenerateToken Method:生成令牌方法:

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

        }

When JWT Bearer token is passed to the API call decorated with [Authorize] and tested with debugger it shows that custom claim like TEMP is not present in the User.Claims List.当 JWT 不记名令牌传递给用[Authorize]装饰的 API 调用并使用调试器进行测试时,它表明像 TEMP这样的自定义声明不存在于User.Claims列表中。

Reading Claims From Token从令牌中读取声明

  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;

Here, the email can be read successfully but I can't read the FirstName from the token.在这里,可以成功读取 email 但我无法从令牌中读取 FirstName。 In fact User.Claims doesn't have the FirstName claim (I mean all the custom claims leaving the Registered JWT Default ClaimTypes), it only has the default token parameters which are emailaddress, id, role etc.事实上, User.Claims没有FirstName声明(我的意思是所有自定义声明都离开了 Registered JWT Default ClaimTypes),它只有默认的令牌参数,即电子邮件地址、ID、角色等。

What should I do?我应该怎么办? should I need to create custom authentication scheme for this purpose?我应该为此目的创建自定义身份验证方案吗?

Internally in AddJwtBearer, there are some remapping done by the Token hander, where claims are renamed, like在 AddJwtBearer 内部,令牌处理程序完成了一些重新映射,其中声明被重命名,例如

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

This mapping can be turned of using:可以使用以下方法关闭此映射:

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

or setting:或设置:

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

The actual mapping can be found here实际映射可以在这里找到

However, I am not sure why the TEMP claim is not found.但是,我不确定为什么找不到 TEMP 声明。 What claims do you actually see in the authenticated User in your controller?您在 controller 中的经过身份验证的用户中实际看到了什么声明? Some claims in some cases are also ignored.在某些情况下,某些声明也被忽略。

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

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