Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The token is not valid yet #146

Open
rsajja79 opened this issue Aug 13, 2024 · 21 comments
Open

The token is not valid yet #146

rsajja79 opened this issue Aug 13, 2024 · 21 comments

Comments

@rsajja79
Copy link

pylti1p3.exception.LtiException: Can't decode id_token: The token is not yet valid (iat)

I'm getting this error. Everytime I try to launch an app from canvas, this is the error I'm getting. It was working for a day or so, I changed some code in launch that deals with nrps to get the role of the user, I'm getting this error.

@hmoffatt
Copy link
Contributor

It means the computer clocks are not synchronized. Use ntp.

@rsajja79
Copy link
Author

Use NTP on the server where this flask application is running?

@hmoffatt
Copy link
Contributor

You need the clocks properly synchronised everywhere - your Canvas server and your flask application server. The error means that there is a difference in the clocks and hence the application can't trust the token.

@sdiemer
Copy link

sdiemer commented Nov 7, 2024

Hello,

I'm facing a similar issue but with servers having correct NTP configurations.
The problem is that the LMS servers are using different NTP servers than the application servers.
The LMS NTP server is in advance of ~0.15 seconds and then when requests are fast enough, the application throws the error The token is not yet valid (iat).
In my case, it is not possible to change the NTP servers used in all implied systems due to internal politics.
Could it be possible to pass the verify_iat setting to pyjwt (source) ?

Regards

@hmoffatt
Copy link
Contributor

hmoffatt commented Nov 7, 2024

You can set the verify options already, by calling set_jwt_verify_options() on your message_launch object.
https://github.com/dmitry-viskov/pylti1.3/blob/master/pylti1p3/message_launch.py#L254

Rather than disabling the iat check altogether, I think what is needed is to add some leeway when calling jwt.decode, at https://github.com/dmitry-viskov/pylti1.3/blob/master/pylti1p3/message_launch.py#L715

Solutions are 1. patch the library, 2. extended MessageLaunch to override validate_jwt_signature to pass the leeway parameter, or 3. disable the built-in iat validation and do your own.

@rsajja79
Copy link
Author

rsajja79 commented Nov 7, 2024

I agree with the response provided above. I was able to resolve the issue by adding the leeway parameter to the MessageLaunch. This adjustment accommodates the minor time discrepancy between the LMS and application servers without disabling the iat check altogether.

@hmoffatt
Copy link
Contributor

hmoffatt commented Nov 7, 2024

I think it would be helpful for MessageLaunch to have a method to set the leeway passed to jwt.decode (set_jwt_verify_leeway perhaps), like it has set_jwt_verify_options.

@sdiemer
Copy link

sdiemer commented Nov 8, 2024

Thank you for your responses.
I searched for explanation on the "leeway" setting of pyjwt, it seems it is only for the expiration date:
https://pyjwt.readthedocs.io/en/latest/usage.html#expiration-time-claim-exp
I will have to make some tests to able to choose a solution among the list you provided.
Regards

@hmoffatt
Copy link
Contributor

hmoffatt commented Nov 9, 2024

I searched for explanation on the "leeway" setting of pyjwt, it seems it is only for the expiration date:

No, it is also applied to the iat validation, see the code: https://github.com/jpadilla/pyjwt/blob/master/jwt/api_jwt.py#L320

sdiemer added a commit to UbiCastTeam/pylti1.3 that referenced this issue Jan 8, 2025
@sdiemer
Copy link

sdiemer commented Jan 8, 2025

I finally got the time to work on this.
I added the method set_jwt_leeway in the MessageLaunch class to handle the definition of the parameter since it is not provided in JWT through the options dict.
You can cherry pick my commit if you want to integrate this change in the project.

Thank you again for your help.

@rsajja79
Copy link
Author

I started getting this error "pylti1p3.exception.LtiServiceException: HTTP response [https://uiowa.instructure.com/login/oauth2/token]: 400 - {"error":"invalid_request","error_description":"the 'iat' must not be in the future"}"

It was working till today. Then I started getting this must not be in the future error. I have a leeway of 120.

@hmoffatt
Copy link
Contributor

It was working till today. Then I started getting this must not be in the future error. I have a leeway of 120.

Do you mean you applied @sdiemer 's patch in order to set the leeway?

Is your system clock synchronized correctly? 120 seconds is a very large discrepancy.

@rsajja79
Copy link
Author

I've had the leeway set even before like I commented on November 7th. 120 is just for testing. I set it to 30 now and still get the error. "

Image

@hmoffatt
Copy link
Contributor

A clock synchronization issue would explain why the problem just started.

@rsajja79
Copy link
Author

How do i disable the iat check? I've set the flag to false in set_jwt_verify_options. It doesnt seem to be doing anything, as I'm still getting the error.

@hmoffatt
Copy link
Contributor

You should be able to call set_jwt_verify_options({"verify_iat": False} on your MessageLaunch instance.

@rsajja79
Copy link
Author

Image

Would chaning the validate_jwt_signature in message_launch.py dont apply the flag?

@hmoffatt
Copy link
Contributor

Wait, the error seems to be that Canvas is rejecting the iat from you, not the other way around. This is in a service call like AGS, NPRS etc. The problem is still the system clock.

@rsajja79
Copy link
Author

Okay, thank you. I will try to reset the system clock in the morning.

@rsajja79
Copy link
Author

You are right. There is something going on with the "message_launch.has_nrps()" or "message_launch.get_nrps()". I removed this form my code, and seems to fix the error. I will take a look at these functions and how its effecting the iat token. I will share my finidng here, if any.

@hmoffatt
Copy link
Contributor

Calls to those services generate a token which is set to the tool consumer (Canvas). The problem is with the iat in the generated token, not the validation of the token received from Canvas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants