JWT无法将标头解码为Base64Url编码的字符串

时间:2017-03-24 15:30:56

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

我有以下代码:

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

3 个答案:

答案 0 :(得分:9)

我遇到此错误,并通过观察错误详细信息发现原因是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>

答案 1 :(得分:1)

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

答案 2 :(得分:0)

JWT库(例如ValidateToken&#39;)要求输入令牌字符串的长度可以被4整除。您可能需要正确填充&#39;输入使其可被4整除;填充字符是等号。 对于第二种方法,您可以确保&#39; tokenString&#39;正确填充&#34; =&#34;使用此代码段:

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