When is JWTSecurityTokenHandler.ValidateToken() actually valid?
Asked Answered
C

1

29

I am attempting to create a token validation method that returns true if a JWT token is valid based on the signature. I don't think I really need to validate everything in the token but what actually signifies a token is valid after calling ValidateToken()? The existence of a principle? The out referenced token contains certain values? Not sure when to return true from this method.

public bool ValidateToken(string tokenString)
{
    var validationParameters = new TokenValidationParameters()
    {
        ValidIssuer = "My Company",
        ValidAudience = ApplicationId,
        IssuerSigningKey = JsonWebTokenSecretKey
    };

    SecurityToken token = new JwtSecurityToken();
    var tokenHandler = new JwtSecurityTokenHandler();
    var principal = tokenHandler.ValidateToken(tokenString, validationParameters, out token);

    return principal != null;
}
Cp answered 30/3, 2015 at 20:11 Comment(0)
C
45

I check all of the claims values manually. I've been searching for a definitive answer to your same question but the only thing I have seen is that the ValidateToken function will throw an Exception if something is wrong, so I begin by wrapping the call in a try-catch and return false from the catch.

That's just my "first-pass" at validating the token, though. Afterwards I do a little more heavy lifting to check certain values manually. For example, I make sure that the unique_name value in the claims section actually exists as a user in my database, that the user has not been deactivated, and other proprietary system stuff like that.

    public static bool VerifyToken(string token)
    {
        var validationParameters = new TokenValidationParameters()
        {
            IssuerSigningToken = new BinarySecretSecurityToken(_key),
            ValidAudience = _audience,
            ValidIssuer = _issuer,
            ValidateLifetime = true,
            ValidateAudience = true,
            ValidateIssuer = true,
            ValidateIssuerSigningKey = true
        };

        var tokenHandler = new JwtSecurityTokenHandler();
        SecurityToken validatedToken = null;
        try
        {
            tokenHandler.ValidateToken(token, validationParameters, out validatedToken);
        }
        catch(SecurityTokenException)
        {
            return false; 
        }
        catch(Exception e)
        { 
            log(e.ToString()); //something else happened
            throw;
        }
        //... manual validations return false if anything untoward is discovered
        return validatedToken != null;
    }

The last line, return validatedToken != null, is purely superstition on my part. I've never seen the validatedToken be null.

Chuvash answered 16/4, 2015 at 22:1 Comment(4)
Looking at the source code, this indeed seems to be the case: ValidateToken will throw on invalid token. github.com/AzureAD/… This is bad design; we shouldn't use exceptions for control flow. But, that's the state of this library today.Cornell
I had to do something similar in my application to test for token validity, but instead of catching any exception and saying the token is invalid, I would suggest doing something like this instead: catch(SecurityTokenException ex) { return false; } catch(Exception){ log("something else happened"); throw; } This way it will only return false if the validate function is actually what threw the error. If something else breaks it won't tell you that your token is invalid.Cattima
tkd_aj: Thanks for the great suggestion. We should always be as explicit as possible with exceptions. I've updated my answer to include your suggestion.Chuvash
But, how can you get claims? for example, username.Hallerson

© 2022 - 2024 — McMap. All rights reserved.