0

I am generating a JWT token in my WindowsService using IdentityModel.Tokens.Jwt, like so:

private JwtSecurityToken GetJwtToken()
    {
        var symmetricSecurityKey = new SymmetricSecurityKey(Convert.FromBase64String(_secretKey));
        var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature);
        return new JwtSecurityToken(
            "myIssuer",
            expires: DateTime.Now.AddMinutes(15),
            signingCredentials: signingCredentials
        );
    }

Then, I am writing that token with JwtSecurityTokenHandler and sending it in a request to a WebAPI controller:

//some code...
// _tokenHandler below is a JwtSecurityTokenHandler
_httpClient.DefaultRequestHeaders.Add("jwtToken", _tokenHandler.WriteToken(GetJwtToken()));
HttpResponseMessage response = await _httpClient.GetAsync(url);
//...

And on the API side, I am trying to validate the token:

public bool Authenticate(string token)
    {
        if (string.IsNullOrEmpty(token))
            throw new ArgumentEmptyException(nameof(token));

        TokenValidationParameters parameters = new TokenValidationParameters
        {
            ValidIssuer = "myIssuer",
            ValidateIssuer = true,
            ValidateLifetime = true,
            IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(SecretKey))
        };

        try
        {
            new JwtSecurityTokenHandler().ValidateToken(token, parameters, out SecurityToken validatedToken);
            return true;
        }
        catch (SecurityTokenException)
        {
            return false;
        }
    }
}

This throws an error below:

IDX12741: JWT: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' must have three segments (JWS) or five segments (JWE).'

And an example of a generated token, which actually looks like two tokens sent at once, which is baffling me:

eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1Nzk2OTc3NzUsImlzcyI6Im15SXNzdWVyIn0.g9Mw7FijNzAzGofll5E44B8cJtOozln3nUjHKgnkdTs,

eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1Nzk2OTc3ODAsImlzcyI6Im15SXNzdWVyIn0.Noc3lC0h_ryH6axlQJ2Kk2a8wcp5eQ0QhBqidfjuujo

Any advice?

dzenesiz
  • 1,388
  • 4
  • 27
  • 58
  • Does the first token really end with a comma? Or was that added by mistake when you asked the question? –  Jan 22 '20 at 14:34
  • I believe it is two tokens that somewhere get concatenated with a comma. But when I paste each of them (no commas or whitespace) into jwt.io, I still get an information that the signature is invalid. – dzenesiz Jan 22 '20 at 14:38
  • @dzenesiz: you need to paste the secret first into jwt.io, then the token. Without knowing the secret, jwt.io can't verify the signature – jps Jan 22 '20 at 14:43
  • @jps oh, didn't know that. I thought this was just validating the format. Will try that, thanx. – dzenesiz Jan 22 '20 at 14:50
  • I think from the code you have shown above, nobody can tell you why have two tokens. How do you send them from client side? The only difference of the two tokens is the exp (5 seconds difference). Maybe they come from two request and your client doesen't overwrite the old one but append the token to the stored one. – jps Jan 22 '20 at 14:50
  • @jsp that's exactly what I thought. I'll try to find out the cause of it and see if the error persists. And edit my question accordingly afterwards. – dzenesiz Jan 22 '20 at 15:33
  • @jsp The problem was the shared instance of HttpClient. It added to the header value, and I expected it to set a new value each time. Thanks for your help, though! – dzenesiz Jan 23 '20 at 09:39

1 Answers1

1

The JWT token was generated correctly, the problem was in a shared instance of HttpClient. Each consecutive call added to the DefaultRequestHeaders jwtToken value.

When I added logic to reset the value before adding new token, it worked:

_httpClient.DefaultRequestHeaders.Remove("jwtToken"); // new
_httpClient.DefaultRequestHeaders.Add("jwtToken", _tokenHandler.WriteToken(GetJwtToken()));
dzenesiz
  • 1,388
  • 4
  • 27
  • 58