JWT解码时字符串声明类型错误?
Posted
技术标签:
【中文标题】JWT解码时字符串声明类型错误?【英文标题】:String Claim Types Error when JWT Decoding? 【发布时间】:2022-01-15 17:00:07 【问题描述】:当我进行登录操作时,JWT 令牌作为响应返回。但是,当我用 JS 解码时,我得到了这个:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: '1', http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: 'RESMAK ', http://schemas.microsoft.com/ws/2008/06/identity/claims/role: 'Administrator', FirmNumber: '1', PeriodNumber: '1', …
FirmNumber: "1"
PeriodNumber: "1"
aud: "Audience"
exp: 1639301639
http://schemas.microsoft.com/ws/2008/06/identity/claims/role: "Administrator"
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: "RESMAK "
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: "1"
iss: "Issuer"
nbf: 1639215239
[[Prototype]]: Object
我想成为这样的人
FirmNumber: "1"
PeriodNumber: "1"
aud: "Audience"
exp: 1639301639
role: "Administrator"
name: "RESMAK "
nameidentifier: "1"
iss: "Issuer"
可能是什么原因? .Net Core 3.1 与 TypeScript 反应
我通过 JwtHelper 类创建令牌
public class JwtHelper
public IConfiguration Configuration get;
private TokenOptions _tokenOptions;
private DateTime _accessTokenExpiration;
public JwtHelper(IConfiguration configuration)
Configuration = configuration;
_tokenOptions = Configuration.GetSection("TokenOptions").Get<TokenOptions>();
public AccessToken CreateToken(User user, List<OperationClaim> operationClaims, UserForLoginDto userForLoginDto)
_accessTokenExpiration = DateTime.Now.AddMinutes(_tokenOptions.AccessTokenExpiration);
var securityKey = SecurityKeyHelper.CreateSecurityKey(_tokenOptions.SecurityKey);
var signingCredentials = SigningCredentialsHelper.CreateSigningCredentials(securityKey);
var jwt = CreateJwtSecurityToken(_tokenOptions, user, operationClaims, userForLoginDto, signingCredentials);
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
var token = jwtSecurityTokenHandler.WriteToken(jwt);
return new AccessToken
Token = token,
Expration = _accessTokenExpiration
;
//securityKey ,signingCredentials ve diger token optionsdan gelen bilgileri toplayarak bir JwtToken Üretiyoruz.
public JwtSecurityToken CreateJwtSecurityToken(TokenOptions tokenOptions, User user, List<OperationClaim> operationClaims, UserForLoginDto userForLoginDto, SigningCredentials signingCredentials)
var jwt = new JwtSecurityToken
(
issuer: tokenOptions.Issuer,
audience: tokenOptions.Audience,
expires: _accessTokenExpiration,
notBefore: DateTime.Now,
claims: SetClaims(user, operationClaims, userForLoginDto),
signingCredentials: signingCredentials
);
return jwt;
private IEnumerable<Claim> SetClaims(User user, List<OperationClaim> operationClaims, UserForLoginDto userForLoginDto)
var claims = new List<Claim>();
claims.AddNameIdentifier(user.Id.ToString());
claims.AddName($"user.FirstName user.LastName");
claims.AddRoles(operationClaims.Select(x => x.Name).ToArray());
claims.AddFirmNumber(userForLoginDto.FirmNumber.ToString());
claims.AddPeriodNumber(userForLoginDto.PeriodNumber.ToString());
return claims;
public static class ClaimExtensions
public const string ClaimTypeFirmNumber = "FirmNumber";
public const string ClaimTypePeriodNumber = "PeriodNumber";
public static void AddName(this ICollection<Claim> claims, string name)
claims.Add(new Claim(ClaimTypes.Name, name));
public static void AddNameIdentifier(this ICollection<Claim> claims, string nameIdentifier)
claims.Add(new Claim(ClaimTypes.NameIdentifier, nameIdentifier));
public static void AddRoles(this ICollection<Claim> claims, string[] roles)
foreach (var role in roles)
claims.Add(new Claim(ClaimTypes.Role, role));
public static void AddPeriodNumber(this ICollection<Claim> claims, string periodNumber)
claims.Add(new Claim(ClaimTypePeriodNumber, periodNumber));
public static void AddFirmNumber(this ICollection<Claim> claims, string firmNumber)
claims.Add(new Claim(ClaimTypeFirmNumber, firmNumber));
我使用 SigningCredentials 作为 SecurityAlgorithms.HmacSha256Signature
public class SigningCredentialsHelper
public static SigningCredentials CreateSigningCredentials(SecurityKey securityKey)
return new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);//GEnellikle bu şifreleme algoritması kullanılır
最后我用 JwtDecode 库解码了令牌 const decodedToken = jwtDecode(response.data.token)
【问题讨论】:
嗯,这些声明类型名称是默认值。您究竟是如何生成 JWT 的? edit你的问题向我们展示 @CamiloTerevinto 我编辑了 【参考方案1】:问题在于 OpenIDConnect/OAuth 和 Microsoft 对声明名称应该是什么有不同的看法,默认情况下 .NET 会在幕后重命名一些声明。
要阻止这种情况,您需要使用以下方式关闭声明映射:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
然后您需要通过设置来告诉 .NET 名称/角色声明的名称应该是什么:
opt.TokenValidationParameters.RoleClaimType = "roles";
opt.TokenValidationParameters.NameClaimType = "name";
有关索赔映射的更多详细信息,请访问:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0
【讨论】:
以上是关于JWT解码时字符串声明类型错误?的主要内容,如果未能解决你的问题,请参考以下文章
尝试解码 Jwt 令牌时出现“尝试解码 Jwt 时发生错误:无法检索远程 JWK 集:”错误