我不明白这个图书馆的运作方式。你能帮帮我吗?
这是我的简单代码:
public void TestJwtSecurityTokenHandler()
{
var stream =
"eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJJU1MiLCJzY29wZSI6Imh0dHBzOi8vbGFyaW0uZG5zY2UuZG91YW5lL2NpZWxzZXJ2aWNlL3dzIiwiYXVkIjoiaHR0cHM6Ly9kb3VhbmUuZmluYW5jZXMuZ291di5mci9vYXV0aDIvdjEiLCJpYXQiOiJcL0RhdGUoMTQ2ODM2MjU5Mzc4NClcLyJ9";
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
}
这是错误:
字符串必须采用紧凑的JSON格式,格式为:Base64UrlEncodedHeader.Base64UrlEndcodedPayload.OPTIONAL,Base64UrlEncodedSignature'。
如果你在jwt.io website中复制流,它可以正常工作:)
答案 0 :(得分:89)
我找到了解决方案,我忘记了投射结果:
var stream ="[encoded jwt]";
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
var tokenS = handler.ReadToken(tokenJwtReponse.access_token) as JwtSecurityToken;
我可以使用以下方式获取声明:
var jti = tokenS.Claims.First(claim => claim.Type == "jti").Value;
答案 1 :(得分:11)
new JwtSecurityTokenHandler().ReadToken("")
将返回SecurityToken
new JwtSecurityTokenHandler().ReadJwtToken("")
将返回JwtSecurityToken
如果仅更改使用的方法,则可以避免在上述答案中进行强制转换
答案 2 :(得分:8)
您需要使用用于生成加密令牌的秘密字符串。 这段代码对我有用:
protected string GetName(string token)
{
string secret = "this is a string used for encrypt and decrypt token";
var key = Encoding.ASCII.GetBytes(secret);
var handler = new JwtSecurityTokenHandler();
var validations = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
var claims = handler.ValidateToken(token, validations, out var tokenSecure);
return claims.Identity.Name;
}
答案 3 :(得分:3)
使用.net核心jwt软件包,可以使用声明:
[Route("api/[controller]")]
[ApiController]
[Authorize(Policy = "Bearer")]
public class AbstractController: ControllerBase
{
protected string UserId()
{
var principal = HttpContext.User;
if (principal?.Claims != null)
{
foreach (var claim in principal.Claims)
{
log.Debug($"CLAIM TYPE: {claim.Type}; CLAIM VALUE: {claim.Value}");
}
}
return principal?.Claims?.SingleOrDefault(p => p.Type == "username")?.Value;
}
}
答案 4 :(得分:2)
扩展cooxkie和dpix答案,当您读取jwt令牌(例如从AD FS接收到的access_token)时,可以将jwt令牌中的声明与声明合并来自“ context.AuthenticationTicket.Identity”,可能与jwt令牌的声明集不同。
为了说明这一点,在使用OpenID Connect的身份验证代码流中,对用户进行身份验证之后,您可以处理事件SecurityTokenValidated,该事件为您提供了身份验证上下文,然后您可以使用它来读取access_token作为jwt令牌,那么您可以将access_token中的令牌与作为用户身份一部分接收到的标准声明列表“合并”:
private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage,OpenIdConnectAuthenticationOptions> context)
{
//get the current user identity
ClaimsIdentity claimsIdentity = (ClaimsIdentity)context.AuthenticationTicket.Identity;
/*read access token from the current context*/
string access_token = context.ProtocolMessage.AccessToken;
JwtSecurityTokenHandler hand = new JwtSecurityTokenHandler();
//read the token as recommended by Coxkie and dpix
var tokenS = hand.ReadJwtToken(access_token);
//here, you read the claims from the access token which might have
//additional claims needed by your application
foreach (var claim in tokenS.Claims)
{
if (!claimsIdentity.HasClaim(claim.Type, claim.Value))
claimsIdentity.AddClaim(claim);
}
return Task.FromResult(0);
}
答案 5 :(得分:0)
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Email, model.UserName),
new Claim(JwtRegisteredClaimNames.NameId, model.Id.ToString()),
};
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Issuer"],
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
然后提取内容
var handler = new JwtSecurityTokenHandler();
string authHeader = Request.Headers["Authorization"];
authHeader = authHeader.Replace("Bearer ", "");
var jsonToken = handler.ReadToken(authHeader);
var tokenS = handler.ReadToken(authHeader) as JwtSecurityToken;
var id = tokenS.Claims.First(claim => claim.Type == "nameid").Value;
答案 6 :(得分:0)
我写了这个解决方案,它对我有用
protected Dictionary<string, string> GetTokenInfo(string token)
{
var TokenInfo = new Dictionary<string, string>();
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(token);
var claims = jwtSecurityToken.Claims.ToList();
foreach (var claim in claims)
{
TokenInfo.Add(claim.Type, claim.Value);
}
return TokenInfo;
}