【问题标题】:JWT Unable to decode the header as Base64Url encoded stringJWT 无法将标头解码为 Base64Url 编码字符串
【发布时间】:2017-08-17 15:04:28
【问题描述】:

我有以下代码:

public async Task<LoginResult> GenerateJwtTokenAsync(string email, string password)
{
    LoginResult loginResult = await _membershipProvider.Login(email, password);
    if (loginResult.Succeeded)
    {
        var symmetricKey = Convert.FromBase64String(Secret);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(loginResult.Claims),
            Expires = DateTime.UtcNow.AddDays(1),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature)
        };

        var stoken = _tokenHandler.CreateToken(tokenDescriptor);
        var token = _tokenHandler.WriteToken(stoken);

        // Check token here to see if it works
        var jwtToken = _tokenHandler.ReadToken(token) as JwtSecurityToken;
        loginResult.JwtToken = token;
    }
    return loginResult;
}

public ClaimsPrincipal ValidateJwtToken(string tokenString)
{

    ClaimsPrincipal principal;

    try
    {
        var jwtToken = _tokenHandler.ReadToken(tokenString) as JwtSecurityToken;

        if (jwtToken == null)
        {
            principal = null;
        }
        else
        {
            var symmetricKey = Convert.FromBase64String(Secret);

            var validationParameters = new TokenValidationParameters()
            {
                RequireExpirationTime = true,
                ValidateIssuer = false,
                ValidateAudience = false,
                IssuerSigningKey = new SymmetricSecurityKey(symmetricKey)
            };

            SecurityToken securityToken;
            principal = _tokenHandler.ValidateToken(tokenString, validationParameters, out securityToken);
        }
    }
    catch (Exception ex)
    {
        principal = null;
    }

    return principal;
}

下面的行完美地读取了令牌,但是当我在第二种方法中实际读取它时,我得到了一个异常。

// Check token here to see if it works
var jwtToken = _tokenHandler.ReadToken(token) as JwtSecurityToken

我已经验证了这两个字符串是相同的,我非常困惑为什么当我真的想为我的生命验证令牌时它停止工作我看不出我做错了什么。请问有什么想法吗?

编辑:

例外

   "IDX10729: Unable to decode the header 'header' as Base64Url encoded string. jwtEncodedString: 'Token here'."

堆栈跟踪:

   at System.IdentityModel.Tokens.Jwt.JwtSecurityToken.Decode(String[] tokenParts, String rawData)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ReadJwtToken(String token)
   at AuthService.ValidateJwtToken(String tokenString) in AuthService.cs:line 57

【问题讨论】:

  • “我遇到了一个异常”——那个异常是什么? 总是提供您收到的任何错误的详细信息...
  • @JonSkeet 抱歉,我打字很快,部分放在标题中,因为这是一个很大的例外,现在将更新:D
  • 您仍然只显示了 InnerException,而且显然只是其中的一小部分。带有 all 内部异常的完整堆栈跟踪会更容易理解。 (鉴于它是一个失败的 type initializer,这似乎使用了不同的代码......)
  • @JonSkeet 抱歉,这一天真的很长,真的没有,哈哈 - 再次更新。
  • jwtEncodedString: 'Token here' 看起来不合适。这是你自己改变的东西,它真的是一个有效的令牌,还是不是?感觉就像你在这里可能有两个不同的字符串,即使你认为它们是相同的。我会添加更多日志记录。

标签: c# asp.net-web-api jwt


【解决方案1】:

我遇到了这个错误,通过观察错误细节发现原因是Newtonsoft.Json dll 没有加载。

System.IdentityModel.Tokens.Jwt.JsonExtensions 试图加载 dll 的 9.0.0.0 版本,但项目使用的是 10.0.0.0 版本。错误详情如下:

System.ArgumentException: IDX10729: ... 无法加载文件或 程序集'Newtonsoft.Json,版本=9.0.0.0,文化=中性, PublicKeyToken=30ad4fe6b2a6aeed' 或其依赖项之一

我通过将此绑定添加到配置来解决:

 <runtime>
    <assemblyBinding  xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

【讨论】:

  • 考虑到如果解决方案在不同的项目中引用了这个组件,可以为此创建多个配置。
【解决方案2】:

我在验证令牌时遇到了同样的错误。我解决了将 Newtonsoft.Json dll 添加到项目中的问题。

【讨论】:

  • 在 NUnit 项目中有同样的问题,而主项目运行良好。发现项目使用了不同版本的Newtonsoft.Json,刷新版本后NUnit问题消失。
【解决方案3】:

JWT 库(例如 ValidateToken')要求输入令牌字符串的长度可以被 4 整除。您可能需要“右填充”输入以使其可被 4 整除;填充字符是等号。 对于您的第二种方法,您可以使用以下 sn-p 确保“tokenString”正确地用“=”填充:

 tokenString= tokenString.PadRight(tokenString.Length + (4 - tokenString.Length % 4) % 4, '=');

【讨论】:

    猜你喜欢
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2021-06-11
    相关资源
    最近更新 更多