![](/img/trans.png)
[英]How to add a database retrieved value custom claim to JWT Token using ServiceStack
[英]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.