C# 如何解码JWT令牌?

C# 如何解码JWT令牌?,c#,.net,jwt,C#,.net,Jwt,我不明白这个图书馆是怎么运作的。你能帮我吗 以下是我的简单代码: public void TestJwtSecurityTokenHandler() { var stream = "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJJU1MiLCJzY29wZSI6Imh0dHBzOi8vbGFyaW0uZG5zY2UuZG91YW5lL2NpZWxzZXJ2aWNlL3dzIiwiYXVkIjoiaHR0cHM6Ly9kb3Vhbm

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

以下是我的简单代码:

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

        var jsonToken = handler.ReadToken(stream);
    }
这就是错误:

字符串需要采用压缩JSON格式,格式为:Base64UrlEncodedHeader.Base64UrlEndcodedPayload.OPTIONAL,Base64UrlEncodedSignature'


如果将流复制到中,效果很好:)

我找到了解决方案,只是忘了转换结果:

var stream ="[encoded jwt]";  
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
var tokenS = jsonToken as JwtSecurityToken;
我可以通过以下方式获得索赔:

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

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


new JwtSecurityTokenHandler().ReadJwtToken(“”)将返回
JwtSecurityToken


如果您只是更改正在使用的方法,则可以使用.net core 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;
    }
扩展answer和answer,当您读取jwt令牌(例如从AD FS接收的access_令牌)时,您可以将jwt令牌中的声明与来自“context.AuthenticationTicket.Identity”的声明合并,这些声明可能与jwt令牌不具有相同的声明集

举例来说,在使用OpenID Connect的身份验证代码流中,在对用户进行身份验证后,您可以处理为您提供身份验证上下文的事件,然后您可以使用它将access_令牌作为jwt令牌读取,然后您可以“合并”作为用户身份的一部分接收的具有标准声明列表的access_令牌中的令牌:

    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);
    }
securitytokenvalidated(SecurityTokenValidatedNotification上下文)上的私有任务
{
//获取当前用户标识
ClaimsIdentity ClaimsIdentity=(ClaimsIdentity)context.AuthenticationTicket.Identity;
/*从当前上下文读取访问令牌*/
string access_token=context.ProtocolMessage.AccessToken;
JwtSecurityTokenHandler hand=新的JwtSecurityTokenHandler();
//阅读Coxkie和dpix推荐的令牌
var tokenS=hand.ReadJwtToken(访问令牌);
//在这里,您从访问令牌读取声明,该令牌可能具有
//申请所需的其他索赔
foreach(令牌中的var索赔。索赔)
{
if(!claimsIdentity.HasClaim(claim.Type,claim.Value))
索赔性质。追加索赔(索赔);
}
返回Task.FromResult(0);
}
然后提取内容

 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;

jwt,io站点解码了它,但是没有签名,所以它是无效的。可能是@MichaelFredgeim的重复你是对的,这是重复的问题。。。但答案是不同的,因为你们使用的版本库我必须先将声明作为声明列表进行转换<代码>((列表)tokenS.Claims.ForEach(a=>Console.WriteLine(a.Type.ToString()+“”+a.Value))您还可以执行以下操作:handler.ReadJwtToken(tokenjwtresponse.access\u token);很抱歉,如果这应该是显而易见的,但是
TokenJwtResponse.access\u token
来自哪里?TokenJwtResponse.access\u token来自哪里?正如其他人已经质疑的那样:“TokenJwtResponse.access\u token”来自哪里?答案中没有关于它的定义或声明,这使得答案对我们许多人来说毫无用处和意义。当您稍后将其重新指定为
out
参数时,为什么将
handler.ReadToken(token)称为SecurityToken
?是否有可能
ValidateToken
失败并保留原始值?右侧krillgar不必强制转换为SecurityToken ValidateToken是否检查过期?或者我需要在解码后自己验证吗?@computrius ValidateToken接受一个
令牌验证参数
,该参数在呼叫前的线路上构造,如答案中所示。这个对象将告诉验证器要检查什么。
 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;