我创建了这样的JwtToken:
X509Certificate2 cert = certificateStore.Certificate;
var now = DateTime.UtcNow;
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor()
{
Subject = new ClaimsIdentity(new[]
{
new Claim(JwtClaimTypes.Subject, upn),
new Claim(REQUEST_TYPE_NAME, requestType),
new Claim(DOMAIN_NAME, domain),
}),
Lifetime = new Lifetime(now, now.AddMinutes(60)),
SigningCredentials = new X509SigningCredentials(cert),
TokenIssuerName = ISSUER
};
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);这是正确的。创建令牌并将其第一个声明命名为"sub“,这是JwtTokenTypes.Subject的内容。我通过jwt web查过了。
问题是,我有这个解决索赔的方法:
if (string.IsNullOrWhiteSpace(token)) throw new MissingTokenException("Token should not be null.");
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = new X509SecurityToken(new X509Certificate2(new X509RawDataKeyIdentifierClause(certificateStore.Certificate).GetX509RawData()));
var validationParameters = new TokenValidationParameters()
{
IssuerSigningToken = securityToken,
ValidateAudience = false,
ValidateActor = false,
ValidIssuer = ISSUER
};
SecurityToken securedToken = new JwtSecurityToken();
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(token, validationParameters, out securedToken);
Claim claim = claimsPrincipal.FindFirst(m => string.Equals(m.Type, REQUEST_TYPE_NAME, StringComparison.OrdinalIgnoreCase));
if (claim != null && !string.Equals(claim.Value, requestType, StringComparison.OrdinalIgnoreCase))
{
throw new MismatchedTokenException("Token is not of the proper type.");
}
upn = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(JwtClaimTypes.Subject) || m.Type.Equals(ClaimTypes.NameIdentifier))?.Value;
domain = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(DOMAIN_NAME))?.Value;在方法的末尾,您可以看到我检查了JwtClaimTypes.Subject和ClaimTypes.NameIdentifiew的索赔名称,前者应该是,后者实际是。
你知道为什么会发生这种转换吗?或者如何防止它们?
发布于 2016-08-25 19:16:08
在此之前,您需要添加:
JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();这清除了jwt声明的映射。
完成映射是为了使jwt声明适应.net类型的声明。如果您要避免映射,则需要设置name和role的声明类型(如果您想从标识(IPrincipal.IsInRole或Identity.Name)中使用它们)。
您可以在创建ClaimsIdentity时执行此操作:
Subject = new ClaimsIdentity(new[]
{
new Claim(JwtClaimTypes.Subject, upn),
new Claim(REQUEST_TYPE_NAME, requestType),
new Claim(DOMAIN_NAME, domain),
}, "<auth type>", "name", "role"),您必须将authType更改为类似cookie的名称,名称和角色声明名称很可能是这样的。
另一种方法是在令牌验证参数上设置它:
var validationParameters = new TokenValidationParameters()
{
IssuerSigningToken = securityToken,
ValidateAudience = false,
ValidateActor = false,
ValidIssuer = ISSUER,
NameClaimType = "name",
RoleClaimType = "role"
};https://stackoverflow.com/questions/39141310
复制相似问题