如何解码 JWT 令牌?

我不明白这个图书馆是怎么运作的,你能帮帮我吗?

下面是我的简单代码:

public void TestJwtSecurityTokenHandler()
{
var stream =
"eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJJU1MiLCJzY29wZSI6Imh0dHBzOi8vbGFyaW0uZG5zY2UuZG91YW5lL2NpZWxzZXJ2aWNlL3dzIiwiYXVkIjoiaHR0cHM6Ly9kb3VhbmUuZmluYW5jZXMuZ291di5mci9vYXV0aDIvdjEiLCJpYXQiOiJcL0RhdGUoMTQ2ODM2MjU5Mzc4NClcLyJ9";
var handler = new JwtSecurityTokenHandler();


var jsonToken = handler.ReadToken(stream);
}

这就是错误所在:

该字符串需要采用紧凑的 JSON 格式,格式为: Base64UrlEncodedHeader. Base64UrlEndcodedPayload.OPTION,Base64UrlEncodedSignature’。

如果您在 Jwt.io 网站中复制流,那么它工作得很好:)

257878 次浏览

我找到了解决办法,只是忘了考虑结果:

var stream = "[encoded jwt]";
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
var tokenS = jsonToken as JwtSecurityToken;

或者,没有演员:

var token = "[encoded jwt]";
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(token);

我可以使用以下方法获得索赔:

var jti = tokenS.Claims.First(claim => claim.Type == "jti").Value;

new JwtSecurityTokenHandler().ReadToken("")将返回一个 SecurityToken

new JwtSecurityTokenHandler().ReadJwtToken("")将返回一个 JwtSecurityToken

如果您只是改变您正在使用的方法,您可以避免上述答案中的强制转换

使用.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;
}
}

您需要用于生成加密令牌的秘密字符串。 这个代码对我很有用:

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;
}

Cooxkie应答和 Dpix应答上扩展,当读取 jwt 令牌(例如从 AD FS 接收的 access _ token)时,可以将 jwt 令牌中的声明与来自“ context”的声明合并。认证通行证。身份”,它可能不具有与 jwt 令牌相同的声明集。

举例来说,在使用 OpenID Connect 的验证代码流中,在用户被验证后,你可以处理事件 SecurityToken 已验证,它为你提供了一个验证上下文,然后你可以使用它来读取 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);
}
  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;

我写这个解决方案,它的工作为我

    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;
}

用这个:

    public static string Get_Payload_JWTToken(string token)
{
var handler = new JwtSecurityTokenHandler();
var DecodedJWT = handler.ReadJwtToken(token);
string payload = DecodedJWT.EncodedPayload;  // Gives Payload
return Encoding.UTF8.GetString(FromBase64Url(payload));
}
static byte[] FromBase64Url(string base64Url)
{
string padded = base64Url.Length % 4 == 0
? base64Url : base64Url + "====".Substring(base64Url.Length % 4);
string base64 = padded.Replace("_", "/").Replace("-", "+");
return Convert.FromBase64String(base64);
}