只是试图理解一个问题,在我看来这是Microsoft System.Security dll中的错误,但可能是我做错了。
我正在尝试自定义实现JWT令牌。我创建了声明和令牌:
var claimsIdentity = new ClaimsIdentity(new List<System.Security.Claims.Claim>()
{
new System.Security.Claims.Claim(ClaimTypes.Sid, "1"),
new System.Security.Claims.Claim(ClaimTypes.Role, "1"),
},"Custom");
var securityTokenDescriptor = new SecurityTokenDescriptor()
{
AppliesToAddress = Keys.Core.WebsiteDomain,
TokenIssuerName = Keys.Core.WebsiteDomain,
Subject = claimsIdentity,
SigningCredentials = signingCredentials,
};
var tokenHandler = new JwtSecurityTokenHandler();
var plainToken = tokenHandler.CreateToken(securityTokenDescriptor);
var signedAndEncodedToken = tokenHandler.WriteToken(plainToken);
return signedAndEncodedToken;
然后我去检索令牌以及用户(SID)和角色值:
var roleId = stream.Claims.SingleOrDefault(x => x.Type == ClaimTypes.Role).Value;
var userId = stream.Claims.SingleOrDefault(x => x.Type == ClaimTypes.Sid).Value;
验证功能:
private static JwtSecurityToken Validate(string signedAndEncodedToken)
{
var tokenHandler = new CustomJwtSecurityTokenHandler();
var plainTextSecurityKey = Keys.Security.TokenSecret;
var signingKey = new InMemorySymmetricSecurityKey(
Encoding.UTF8.GetBytes(plainTextSecurityKey));
var tokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = signingKey
};
SecurityToken validatedToken;
tokenHandler.ValidateToken(signedAndEncodedToken, tokenValidationParameters, out validatedToken);
var jwtToken = validatedToken as JwtSecurityToken;
return validatedToken as JwtSecurityToken;
}
现在,我的用户ID(ClaimType.SID)似乎正确返回,但是我的RoleId(ClaimType.Role)作为不存在回来。如果我更改x.Type ==“ role”,它将正常工作。
在对Claim.Type SID的检查中显示为:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid
但是Claim.Type角色显示为:角色。
ClaimTypes.Role具有完整的架构路径。
这是错误,还是我缺少什么?
我意识到某个时候过去了,但是作为对此也感到惊讶的人,我的确在JwtSecurityToken.Claims
属性上遇到了此评论:
返回的声明将不会根据Claim.Type
翻译了JwtSecurityTokenHandler.InboundClaimTypeMap
因此,如果您想在解码的令牌中搜索时使用ClaimTypes
,则可以通过该词典运行它,并知道您没有疯癫或做错了什么。
Assert.Equal(
"Nicholas Piasecki",
parsedToken
.Claims
.Single(x =>
{
var map = JwtSecurityTokenHandler.DefaultInboundClaimTypeMap;
if (map.TryGetValue(x.Type, out var mapped))
{
return mapped == ClaimTypes.GivenName;
}
return false;
})
.Value);