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

Increase default OIDC session-age-extension to minimize chances of dropping expired ID tokens #41745

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sberyozkin
Copy link
Member

@sberyozkin sberyozkin commented Jul 7, 2024

This PR is really only about improving an OIDC authenticated user experience than fixing anything OIDC specific, following several discussions with users, the last one being with @calvernaz a few weeks back related to a difficult to trace issue with #41015.

So, the OIDC session cookie serves the only purpose: keep an ID token (directly in the encrypted form or indirectly via a reference to some custom token state manager's state) and make it available to Quarkus whenever an already authenticated user tries to access Quarkus again, for OIDC be able to analyze this ID token: confirm it is valid, refresh if it has expired or redirect the user to a session expired page in order to explain to the user that the session has expired.

If the session cookie has expired, then the browser drops it and Quarkus does not know that the current user authenticated and therefore must treat it as a new request and redirects the user to OIDC provider to authenticate.

It leads to a rather poor user experience. For example, imagine you have authenticated to an airline's website, stayed idle for a bit longer that than the session age is, now you click on your order and you see a request to enter name and password at the SSO OIDC provider login page, without any explanation.

So extending the session cookie's max-age to a few hours by default simply minimizes the chances of the expired ID token being dropped together with its session cookie container and thus giving OIDC a chance to do something about this expired ID token - for example, auto-refresh it if the token refresh is allowed, or, redirect the user to a session expired page where a user can be explained the sessin has now expired, and offered a link to re-authenticate.

Also, extending the session cookie's max-age does not change the real user session's age, that of the ID token.

Fixes #41130.

I've set to 5 hours by default but it can probably be set to 8 hours or more at a later stage. Users can tune it further as needed, this PR is about trying to help users avoid having to set this property in real prods, since without it, the expired ID token is always lost and users would see re-authentication screens without any hints as to what has happened.

CC @calvernaz

@sberyozkin sberyozkin requested a review from pedroigor July 7, 2024 18:35
@quarkus-bot quarkus-bot bot added area/docstyle issues related for manual docstyle review area/documentation area/oidc labels Jul 7, 2024

This comment has been minimized.

This comment has been minimized.

@sberyozkin sberyozkin force-pushed the oidc_increase_session_token_age branch from faf22df to bc24a11 Compare July 7, 2024 21:28
@sberyozkin
Copy link
Member Author

sberyozkin commented Jul 7, 2024

Sorry, forgot to check oidc-wiremock tests which actually compare the age of the session cookie with the age of the ID token which this cookie keeps encrypted. These tests confirm that by increasing the session age extension, it is the session cookie age which is increased, the real session age, ID token's age, remains the same.

I.e, if the session cookie age is bigger than the ID token's age by a few hours then if the user remains idle for longer than the token's age but still less than the session cookie's age, the chance of Quarkus seeing this expired ID token and doing a useful action with it increases

This comment has been minimized.

This comment has been minimized.

@sberyozkin
Copy link
Member Author

We have agreed with @pedroigor to avoid changing the default session-age-extension property to avoid even slightest security concerns, esp if the session cookie encryption is turned off.
I'll revert the property update but keep the doc updates as they make it now much clearer how users can manage this property if they require it

@sberyozkin sberyozkin force-pushed the oidc_increase_session_token_age branch from bc24a11 to 33564d7 Compare July 17, 2024 12:31
@sberyozkin
Copy link
Member Author

Hi Pedro @pedroigor, after thinking more about it, I've tried to rework it, instead of increasing the max-age by 5 hours no matter what. Essentially keeping it nearly exactly as it is currently on the main branch, where the cookie max-age is increased with this property value only if the refresh token is required and the RT is present and I added extra check if the session expired path is available.

The only impactful change is that it is an optional 1 hour extension, instead of 5 mins. 1 hour appears to be the bare minimum to me if users enable the token refresh. They will certainly have to set this property manually otherwise in this case.

Hopefully an 1 hour optional extension (only if the user wants the token refresh or session expired page redirect to work) is all right, compared to the previous attempt of a 5 hours extension in all the cases...

This comment has been minimized.

This comment has been minimized.

@sberyozkin
Copy link
Member Author

Hi @pedroigor and also @gastaldi, let me check again here (PR needs a rebase, I can do it later).

Let me summarize what this PR does here, I did it above, but it was awhile back...

So quarkus-oidc uses a session cookie to keep the encrypted ID token:

  • ID token validity determines how long the authenticated user's session is valid for. If ID token is valid for 1 hour then after 1 hour the user has to re-authenticate unless ID token gets refreshed by quarkus-oidc
  • The session cookie validity (max age) only determines how long this cookie can keep the ID token for . It does not impact in anyway how often the authenticated user has to be re-authenticated. Its only purpose is to provide a storage for the encrypted ID token.
  • The main reason the session cookie max-age should be ideally and in fact typically be longer than the ID token's max age is to deliver, possibly an expired ID token, to Quarkus. If the session cookie age is the same as the ID token age, then, with ID token being valid for 1 hour, after 1 hour 1 min, the session cookie, and hence the ID token will be removed from the browser cache - and when the already authenticated user returns to Quarkus - it is a new user for Quarkus as it will find no session cookie and no ID token
  • It does not matter if the session cookie keeps an encrypted ID token, or if the ID token is saved in the server DB and the session cookie keeps only a DB pointer - if the session cookie expires - then this DB pointer is lost together with the session cookie, making the ID token stored in DB orphaned and eligible for the removal.
  • However, if the session cookie age is longer than the ID token age then, the important point is, the chance of Quarkus being able to act on expired ID tokens increases, the bigger the difference, the higher the chance of Quarkus being able to refresh the expired tokens for example.
  • By default, the session cookie age is equal to the ID token age which means if the ID token has expired then it means the session cookie has expired and the browser will drop it
  • It is 100% guaranteed that if users want to have expired ID tokens refreshed by Quarkus, they will have to configure a session age extension property to make the session cookie age bigger that the ID token age by the configured value. The reason it is guaranteed is explained in the previous bullets - to increase chances for Quarkus to do something about the expired ID tokens. If users don't configure it then Quarkus will never see expired tokens and won't be able to meet the user's requirement to refresh tokens

So all this PR does it tries to help users avoid having to configure the session age extension property - when it is required anyway to have the session cookie age extended - for example, to have expired tokens refreshed. This is a dev experience issue more than anything else - and is about 1 less property to configure (it was mentioned in the OIDC survey).

It extends the session cookie age by 1 hour only which is a bare minimum for such cases...

Copy link
Contributor

@gastaldi gastaldi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I'll let @pedroigor have the final say on this PR ;)

@sberyozkin
Copy link
Member Author

Thanks @gastaldi, I'll wait for @pedroigor to double check.
One more note here: this PR does not make Quarkus a decision maker related to the session age extension, without the users even being aware. Quarkus will only extend it by the minimum 1 hour period if the user has made the indirect decision it is necessary by requesting that the expired tokens must be refreshed. If Quarkus does not do it it, when the user forgets it, all we'll get is the users asking questions why the tokens are not refreshed and opening bug issues (in fact it happened several times)

Copy link
Contributor

@MichalMaler MichalMaler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @sberyozkin . I see a lot of good work has been done on these files. I decided to provide a little review when applying one sentence per line and some Vale tweaks on the way.

@sberyozkin
Copy link
Member Author

@MichalMaler Thanks for having a look, I've just realized it is done against the existing PR, please consider opening a dedicated PR.

@sberyozkin
Copy link
Member Author

@MichalMaler You are right, this is all specific to this PR, I'll deal with your comments, thanks

Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need squashing and I added a question.

@sberyozkin sberyozkin force-pushed the oidc_increase_session_token_age branch from 52696e8 to 46adbb2 Compare December 17, 2024 15:32
Copy link

github-actions bot commented Dec 17, 2024

🎊 PR Preview 9943ebd has been successfully built and deployed to https://quarkus-pr-main-41745-preview.surge.sh/version/main/guides/

  • Images of blog posts older than 3 months are not available.
  • Newsletters older than 3 months are not available.

This comment has been minimized.

This comment has been minimized.

@sberyozkin sberyozkin force-pushed the oidc_increase_session_token_age branch from 46adbb2 to b67e1d3 Compare December 17, 2024 22:30
Copy link

quarkus-bot bot commented Dec 17, 2024

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit b67e1d3.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

Copy link

quarkus-bot bot commented Dec 17, 2024

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit b67e1d3.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@cescoffier
Copy link
Member

@gsmet Are you ok with the changes now?

@sberyozkin
Copy link
Member Author

sberyozkin commented Jan 12, 2025

@cescoffier Ideally, @pedroigor would also approve, but overall it looks safe to me, the only alternative is for users manually add the same configuration whenever they require Quarkus to refresh tokens.
The lifetime of the actual OIDC session is definitely not impacted, the only thing which is changed is the cookie lifetime is increased a little bit.
The cookie can last for a week, it won't impact the fact that the OIDC session may be valid for 1 hour (ID token age), all increasing the session cookie lifetime does is making sure that if, in this example, the user logs in, then returns tomorrow, in 1 day, Quarkus will be able to detect the expired ID token and refresh it if required by the configuration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/docstyle issues related for manual docstyle review area/documentation area/oidc
Projects
Status: Review pending
Development

Successfully merging this pull request may close these issues.

Set quarkus.oidc.authentication.session-age-extension to a larger value by default and clarify its purpose
5 participants