Validate the JsonWebKey using nbf and exp

Issue #62 closed
Vinoj Mathew created an issue

HI there,

One of our requirement is to check the jsonwebkey using nbf and exp, eventhough it has matching kid,alg,use etc. is there any way we can do it. When we debug the code they way i can see with limited code change

1) make changes to abstract class JsonWebKey and add nbf and exp with get/set method

private Long nbf;

private Long exp;

protected JsonWebKey(Map<String, Object> params)
    {
        setUse(getString(params, USE_PARAMETER));
        setKeyId(getString(params, KEY_ID_PARAMETER));
        setAlgorithm(getString(params, ALGORITHM_PARAMETER));
        setExp(getLong(params, EXP_PARAMETER));
        setNbf(getLong(params, NBF_PARAMETER));

    }

 protected static Long getLong(Map<String, Object> params, String name)
    {
        return JsonHelp.getLong(params, name);
    }

2) change to SimpleJwkFilter ---> where in the filter method before adding the jsonwebKey to the list we check for the nbf and exp, if exist check the validity, that kid is within the limit of nbf and exp only if exist

 public List<JsonWebKey> filter(Collection<JsonWebKey> jsonWebKeys)
    {
        List<JsonWebKey> filtered = new LinkedList<>();
        for (JsonWebKey jwk : jsonWebKeys)
        {
            boolean match = isMatch(kid, jwk.getKeyId());
            match &= isMatch(kty, jwk.getKeyType());
            match &= isMatch(use, jwk.getUse());
            match &= isMatch(alg, jwk.getAlgorithm());
            String[] thumbs = getThumbs(jwk, allowThumbsFallbackDeriveFromX5c);
            match &= isMatch(x5t, thumbs[0]);
            match &= isMatch(x5tS256, thumbs[1]);
            match &= isMatch(crv, getCrv(jwk));

            if (match && isKeyValid(jwk))   //** this is method to check the nbf and exp**
            {
                filtered.add(jwk);
            }
        }
        return filtered;
    }

Is there any better way we can do this.

Thanks

Comments (7)

  1. Brian Campbell repo owner

    So exp and nbf aren't standard JWK parameters. I probably should but I haven't really provided a way to deal with custom JWK parameters. So something like what you've got there is probably the way to go (you might also want to use org.jose4j.jwt.NumericDate if your JWK exp and nbf are meant to have the same semantics as the JWT claims of the same name). Unfortunately, however, that requires modifying the code.

    I might also try and better understand the reason behind the requirement you have and see if there's a way to achieve it without using nonstandard parameters and a forked library.

  2. Vinoj Mathew reporter

    Thanks Brian for the quick response.

    Yes we accept the fact that exp and nbf aren't the standard JWK parameter.

    The reason for adding nbf and exp on the JWK parameter is that lets say the hackers may get one of our keys and we can mark it as expired(exp),if not the library will keep accepting the tokens signed by it

    Since we are using the library the only way I can change it forked the current workset and make the changes for our use,unless if you can help me custom jwk parameter.

    By the way I was supposed to use the Numericdate after signed the token and validation of the claim

    1) but the challenge for me sometimes on demand we need to override the expiry date -- the way we overide is user can set the overide in seconds with userdefined fields and we add like current nbf +overideoffset as the expiry date

    2) like the validator class -->its very useful --> but for the audienceValidator we are considering like if the user set the list of audience value we need to match all the user provided audience with the token audience ----> currently it woks like if any one of the user provided audience list is matching with the token it will return true

    thanks

  3. Brian Campbell repo owner

    I created Issue #63 "support additional/arbitrary JWK parameters" with the intention of adding more support for custom JWK parameters at some point. I can't say when I'll get to it our have a release with that in it, however.

    You say, "The reason for adding nbf and exp on the JWK parameter is that lets say the hackers may get one of our keys and we can mark it as expired(exp),if not the library will keep accepting the tokens signed by it" - why not remove the key rather than mark it as expired? If the token consumer can pick up the list of keys with the new expirations, seems like it could also get the list that has keys removed. Maybe I just don't understand.

    Not sure what you mean about NumericDate. There's a setAllowedClockSkewInSeconds(...) on JwtConsumerBuilder that maybe can help with some leeway offset in times when consuming the token. If you need offset when producing, it might be better to just extend the times. But again, I'm not sure I understand.

    The AudValidator works per the JWT RFC https://tools.ietf.org/html/rfc7519#section-4.1.3 and I'd again suggest considering carefully before you deviate from the standard. If you really want your own aud validation you can use JwtConsumerBuilder's setSkipDefaultAudienceValidation() and then plug in your own with registerValidator(...).

  4. Vinoj Mathew reporter

    Really appreciate Brian your thoughts. Our requirement on NumericDate/AudValidator is slightly different. Appreciate your response on this. Currently as mentioned and I am doing using registerValidator

    For nbf/exp we are on the receiving side. So need to work on nbf/exp. So Is there any way you can help us with a quick fix for setting up the additional/arbitrary JWK parameters

    thanks for the help

  5. Brian Campbell repo owner

    with b1672dd JsonWebKey and the EC/RSA/OCT classes that extend from it can deal with unknown/additional parameters when parsing and serializing from/to JSON. And JsonWebKey has two new methods to get/set such parameters:

        public void setOtherParameter(String name, Object value)
    
        public <T> T getOtherParameterValue(String name, Class<T> type)
    

    You could extend SimpleJwkFilter or just do a second pass over the list returned from filter(...) and apply the additional checks you need.

  6. Log in to comment