c# - 解码jwt错误:无法将有效载荷解码为Base64Url编码的字符串

我有一个jwt令牌'eyJhbGciOiJIUzI1NiJ9.YUExIQ.srnc87a8Se8arhCopLBpgxEvILA2AZxOB8BIrFDHKL4
'
那是在节点中编码的,而我试图在c#中对其进行解码,但是我收到一个错误消息,它对有效负载感到不满。

    public void Consume(BasicDeliverEventArgs msg)
    {
        var message = Encoding.UTF8.GetString(msg.Body);
        var user = JsonConvert.DeserializeObject<User>(message);

        var handler = new JwtSecurityTokenHandler();

        try
        {    
            var x = handler.ReadToken(user.Password) as JwtSecurityToken;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }



        _repo.UpdateUser(user);
    }


返回错误:无法将有效负载“ YUExIQ”解码为Base64Url编码的字符串

我不确定是否可以在某个地方放置用于解码的编码秘密,或者我是否需要将有效负载转换为base64,或者我是否只是在某个地方缺少某些步骤。提前致谢。

最佳答案

自从您询问使用Base64进行解码以来,我将重点讨论该问题,而不是.NET中JWT的语义。这应该使JWT令牌有点神秘。

请注意,只有上面的JWT字符串的第一段有效-转换为{"alg":"HS256"},第二段转换为aA1!-因此,例如,我将使用http://jwt.io中的默认样本值:

var jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";


因此,对于每个JWT.io's introduction,JWT令牌中只有三个段:


标头
有效载荷
签名


假设令牌未加密,则可以使用普通的Base64解码前两个段(一旦将长度填充为4的倍数,如上述@Jacob所述)。最后一部分只是一个加密签名。它不包含任何有意义的编码信息进行解码。

因此,用于显示已解码的JWT内容的简单代码段如下所示:

var decoded = jwt.Split('.')
  .Take(2)
  .Select(x => 
    Encoding.UTF8.GetString(
      Convert.FromBase64String(
        x.PadRight(x.Length + (x.Length % 4), '='))))
.Aggregate((s1, s2) => s1 + Environment.NewLine + s2);

Console.WriteLine(decoded);

/* Prints:
   {
     "alg": "HS256",
     "typ": "JWT"
   }
   {
     "sub": "1234567890",
     "name": "John Doe",
     "admin": true
   }
*/


分隔所有lambda的一个简单示例如下所示:

/// <summary>
/// A function to make the Base64 decoding a little less
/// verbose below:
/// </summary>
string Base64Decode(string value)
{
    return Encoding.Default.GetString(Convert.FromBase64String(value)); 
}

// Get the first two segments into an enumerable:
var pieces = jwt.Split('.').Take(2);
// Pad them with equals signs to a length that is a multiple of four:
var paddedPieces = pieces.Select(x => x.PadRight(x.Length + (x.Length % 4), '='));
// Base64 decode the pieces:
var decodedPieces = paddedPieces.Select(x => Base64Decode(x));
// Join it all back into one string with .Aggregate:
Console.WriteLine(decodedPieces.Aggregate((s1, s2) => s1 + Environment.NewLine + s2));


这里的结果与上面的结果相同。

当然,现在,如果您打算进行有意义的JWT操作(如签名和验证),则应使用JwtSecurityToken中的System.IdentityModel.Tokens.Jwt类。但是,如果您只需要找出未加密令牌包含的信息,就和上面一样简单。

本文翻译自 https://stackoverflow.com/questions/43074897/

网站遵循 CC BY-SA 4.0 协议,转载或引用请注明出处。

标签 c# node.js base64 jwt


相关文章:

c# - 如何用C#在Mono上编写基于REST的简单服务器? [关闭]

c# - 使用func指向属性设置值

c# - 计时器之谜-Forms.Timer与Threading.Timer

c# - Windows哈希密码

c# - 从C#.Net Core项目正确调用外部C库方法*在Linux上*

c# - 如何从C#调用Spotify API

c# - 代码编辑器Visual Studio 2013中缺少颜色

c# - 为什么Regex会挂在C#中

c# - 异步/等待取消机制

c# - Asp.Net核心长期运行/后台任务