只是试图理解一个问题,我脑子里出现的问题是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;
}
现在我的UserID(ClaimType.SID)似乎正确返回,但我的RoleId(ClaimType.Role)回来时不存在。如果我更改x.Type ==“role”,它可以正常工作。
在检查Claim.Type时,SID显示为:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid
但Claim.Type Role显示为:Role。
ClaimTypes.Role具有完整的架构路径。
这是一个错误,还是我错过了什么?
答案 0 :(得分:1)
我意识到某个时候已经过去了,但是作为对此也感到惊讶的人,我的确遇到了有关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);