auth0 / java-jwt

Java implementation of JSON Web Token (JWT)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

token is still alive, when "exp" = NOW

taisuke-fujimoto opened this issue · comments

Describe the problem

I tried with the code below, but no exception occurred. (TokenExpiredException occurs when Clock is +1 second)
This means that token lifetime is NOW <= "exp"

// kotlin code
val expiresAt = Instant.now()
val token = JWT.create()
    .withExpiresAt(expiresAt)
    .sign(Algorithm.HMAC256("test"))

val verifier = (JWT.require(Algorithm.HMAC256("test")) as JWTVerifier.BaseVerification)
    .build(Clock.fixed(expiresAt, ZoneId.of("UTC")))

verifier.verify(token)

Shouldn't the token lifetime be NOW < "exp"?

I think this description is correct.
https://github.com/auth0/java-jwt/blob/master/EXAMPLES.md#datetime-claim-validation

Environment

  • Version of this library used: 4.2.1
  • Version of Java used: 11
  • Other modules/plugins/libraries that might be involved: Kotlin 1.7.22

Hey @taisuke-fujimoto, thanks for the issue and test case. Yes, the specification states that the exp must be before the current time, so it looks like there is an off-by-1 second here.

The problem is in the assertInstantIsFuture method.

The specification states:
The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim.

That means:

  • A token isn't expired and valid if NOW < exp
  • A token is expired if NOW >= exp

The method assertInstantIsFuture checks for a valid token with:

  • !now.isAfter(exp) => !(NOW > exp)

The correct way should be:

  • NOW < exp => now.isBefore(exp)