Open tn185075 opened 8 months ago
Also relevant https://datatracker.ietf.org/doc/html/rfc6749#section-1.5
The refresh flow explicitly states new tokens are issued. Obviously this is void of any context regarding the JWT Profile but likely applies.
If approved as bug, I'd be glad to raise a PR fixing it.
Bumping up ‼️
I can confirm that iat
gets updated in ID tokens, but not access tokens. I think you should just do a PR with tests for this.
So it looks this is more confusing than one would hope for.
For ID Tokens:
RequestedAt
is set to time.Now().UTC()
when (default) IDTokenSession
is created. That is used for rat
claim.IssuedAt
claim is set to time.Now().UTC()
when ID token is being generated. That is used for iat
claim.This seems reasonable. rat
claim seems to be specific feature of Fosite. And it might be reasonable that it does not
change on refresh. That it shows when the original ID token was requested.
For access tokens:
RequestedAt
is set to time.Now().UTC()
when (default) Requester
is created.IssuedAt
is then set to time.Now().UTC()
when generating access token using WithDefaults
in DefaultJWTStrategy
, but only if it has not already been set. This is used for iat
claim.RequestedAt
is used as the issued timestamp.response["iat"] = r.GetAccessRequester().GetRequestedAt()
, this works because in AccessTokenJWTToRequest
, RequestedAt
is set from IssueAt
from iat
in the token itself.
AccessTokenJWTToRequest
attempts to read rat
claim, but that is never set on access tokens, only ID tokens.I find this confusing. There are two names (RequestedAt
and IssuedAt
) used for the same thing and also two places to save it (one in requester, the other in JWK claims).
Anyway, my workaround for this is that I set IssuedAt
every time GetJWTClaims()
is called.
Sorry, in fact no, it does not work correctly. By default AccessTokenJWTToRequest
is not used but a standard introspection is used instead. And I tested this now and it can happen that the iat
in the response is different from the iat
in the JWT token. iat
in the response uses GetRequestedAt
, but iat
timestamp in JWT is generated using time.Now().UTC()
.
So the problem is even in the initial access token. And another issue is that after refresh the iat
is not updated.
Workaround in introspection handler:
ar := ir.GetAccessRequester().(*fosite.AccessRequest)
ar.RequestedAt = ar.GetSession().(*oauth2.JWTSession).JWTClaims.IssuedAt
oidc.WriteIntrospectionResponse(ctx, w, ir)
I found another issue In HMACSHAStrategy
's ValidateAccessToken
, access token's GetRequestedAt
is used to validate the token. But because refreshed access tokens keep original issue time, those refreshed access tokens are valid even before the real issue time (the time they have been issued).
Preflight checklist
Ory Network Project
No response
Describe the bug
Please assume the following flow:
iat
field pointing to the time, the original access token was created.iat
set to9:00
andexp
set to9:31
.iat
field should be indicative of when this JWT was issued.Reproducing the bug
Please reproduce the above mentioned steps, with any OAuth server powered by fosite :)
Relevant log output
No response
Relevant configuration
No response
Version
v0.42.2
On which operating system are you observing this issue?
Linux
In which environment are you deploying?
Kubernetes
Additional Context
No response