AccessToken is not (yet) valid

In short: it seems if we want to use an accessToken too fast!? (that we freshly got from auth0) on our BackEnd, then we get Unauthorized exception from our Backend. If we add some delay in between retrieving the accessToken on our Frontend and first time using it on our Backend, then there’s less chance to get the error.

Details: we have a spring boot Backend app and a single page Frontend written in React.
We are using universal login to get accessToken from auth0. Right after getting redirected to our Frontend and getting the accessToken, we are making a Backend call which uses the fresh accessToken and sometimes it fails sometimes doesn’t. We experience that if we add some delay at the above mentioned place, then the issue is less likely to occur.

We have a custom SecurityConfig class in spring which uses JwtWebSecurityConfigurer from auth0 the following way:

open class SecurityConfig : WebSecurityConfigurerAdapter() {

    @Value(value = "\${auth0.apiAudience}")
    lateinit var apiAudience: String

    @Value(value = "\${auth0.issuer}")
    lateinit var issuer: String

    override fun configure(http: HttpSecurity) {
            .forRS256(apiAudience, issuer)
            .mvcMatchers(HttpMethod.PUT, "/users/profile").authenticated()

At the endpoint PUT /users/profile we save some userInfo on our Backend, and this is the first endpoint that gets called on successful authentication, and it has to be an .authenticated() call.
And this is the point where in some cases Backend rejects the call with Unauthorized exception even tho Frontend just got a fresh new accessToken from auth0. But as I said, it’s flaky. Sometimes it works without delay, sometimes even 2500ms delay is not enough and we still get Unauthorized from Backend. As we experienced, system clock is also affecting this error: the more it’s unsynchronized, the bigger the chance we get the exception.

Thanks for any help/advice!

Hi @info40,

Sounds like a clock skew issue. You can add some leeway to your expiration time. Are you using the auth0 SPA sdk in your front end? If so, you can send a leeway param with your request. Here is the doc for it:

Hi dan.woda,

yeah it definitely behaves like it was a clock issue (at one occasion with a colleague the solution was to manually sync the system clock), and very flaky, very inconsistent, so hard to reproduce. We use auth0-lock & auth0-js libs on our React FE with universal login, I found that we can set this leeway param there too.

However, setting up leeway to 100 it does not seem to help, here’s what I found:
After a fresh login, I get an accessToken which expires at ... 8:52:45 AM (by iat field of accessToken payload), and then our FE first calls our BE with this token at ...08:52:44 AM (by chrome console log).
Of course the token is not yet valid, but how is this possible!? I first create & get the token and then I’m using it.

Thanks for your reply & help so far,

The iat claim is the ‘issued at’. So you are saying it is issued at 8:52:45, and is being validated at 8:52:44 (which is before the token is issued).

This is likely because the server validating the token has a skewed clock. Setting a leeway should solve this. Can you post the code you are using to make the request with the leeway param?

1 Like


so as I’m reading the documentation, the leeway by default is never 0, it seems that the default is 30 seconds (but it’s not consistent and not explicit in the docs for me). And the offset is 1-2 seconds between the servers, so the default leeway should solve the problem but it doesn’t for me.

So my current workaround (I have a super busy period, I don’t have time to play around with this more) is that on our BE in case of such validation error during accessToken verification (InvalidClaimException in java) I decode the token without validation, check the issuedAt date and current time and put the current Thread to sleep for that time difference. This is usually not more than 1 seconds and happens only on first use of accessToken after login.

This is just a temporary hack till I make leeway or other better solution to work, but as I said I added it at one point with 100sec and didn’t change anything. Haven’t tried to provide it as both String and Int, I might missed sg there.

1 Like

Okay, let us know what happens once you have time to confirm it.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.