LukeHennerley
LukeHennerley

Reputation: 6434

JWT Unable to decode the header as Base64Url encoded string

I have the following code:

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

The line below reads the token perfectly, however when I actually read it in the 2nd method I get an exception.

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

I have verified the two string are identical, I am extremely confused as to why this stops working when I actually want to validate the token for the life of me I can't see what I am doing wrong. Any ideas please?

EDIT:

Exception

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

Stack trace:

   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

Upvotes: 9

Views: 25442

Answers (5)

Akter
Akter

Reputation: 766

In my case, when this package [System.IdentityModel.Tokens.Jwt] MISSING, I got the slight similar exception like:

"IDX12729: Unable to decode the header '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' as Base64Url encoded string. jwtEncodedString: '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'."

Upvotes: 2

Tom&#225;s V&#233;lez
Tom&#225;s V&#233;lez

Reputation: 51

Try updating the library to a most recent version. In my case, System.IdentityModel.Tokens.Jwt, Version=6.5.0.0 solved the problem.

Upvotes: 2

MiguelSlv
MiguelSlv

Reputation: 15113

I was having this error and found, by observing the error detail, that the cause was that Newtonsoft.Json dll was not loaded.

The System.IdentityModel.Tokens.Jwt.JsonExtensions was trying to load version 9.0.0.0 of the dll but the project was using version 10.0.0.0. The error detail have something like this:

System.ArgumentException: IDX10729: ... Could not load file or assembly 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies

I resolved by adding this binding to the config:

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

Upvotes: 17

user8516772
user8516772

Reputation: 11

I was getting the same error validating the token. I solved adding the Newtonsoft.Json dll to the project.

Upvotes: 1

Mark D.
Mark D.

Reputation: 129

The JWT library (e.g. ValidateToken') requires input token strings that have a length that is divisible by 4. You may need to 'right pad' the input to make it divisible by 4; the padding character is the equals sign. For your second method, you can make sure that 'tokenString' is properly right padded with "=" by using this snippet:

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

Upvotes: -1

Related Questions