OpenConext / OpenConext/OpenConext-engineblock
Remember choice for WAYF per SP
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 17
- Forks
- 25
- Avg merge
- 4d 1h
- Merged PRs (30d)
- 1
Description
It is already possible to show a checkbox in the WAYF that allows users to save this IdP-choice for future logins. If they select this, then future WAYFs in which their preferred IdP is present are skipped and the user is redirected to the preferred IdP without interaction.
We now want to able to specifiy this behaviour per SP. So when a users enabled the checkbox, this only applies when logging in to this specific SP. When the user logs in to a different SP, they still get the WAYF.
The following changes are required:
-
Add the following extra controls to
parameters.yml:- introduce feature-toggle
wayf.remember_choice_per_idp. All of the below should only be active if bothwayf.remember_choiceandwayf.remember_choice_per_idpare active.- If
wayf.remember_choiceis true andwayf.remember_choice_per_idpis false, we keep the current global memory feature. - If
wayf.remember_choiceis false, we disable all remember-my-choice features (both global and per-sp). - If
wayf.remember_choice_per_idpis not defined, act as if it were set tofalse
- If
- a parameter to control the life-time of the remembered IdP:
wayf.remember_choice_per_idp_lifetime. Typically this would be something like 3 months, but it would be nice to be able to set it to (e.g.) 60 seconds for easy debugging. - a parameter to control how many SP-IdP pairs we can store in the cookie
wayf.remember_choice_per_idp_lifetime. This defaults to16. For the logic what to do if we exceed this limit, see below.
- introduce feature-toggle
-
support new
coin:wayf_remember_choicemetadata parameter for SPs. If this is not present in the metadata, it defaults tofalse. -
if feature is enabled, read and set a cookie
rememberedidpswith content like this:{ "https://sp_entityid_1": { "idp": "https://idp_entityid_1", "expires": 1784534287 }, "https://sp_entityid_2": { "idp": "https://idp_entityid_2", "expires": 1784512345 } }- Ideally, we would like this cookie to be user-readable (for power users and privacy nerds), but cookies are limited to 4kB so that probably won't work. So the safe way to handle this is to deflate and base64-encode the json, en put that in the cookie.
- To make sure the structure fits in the cookie, limit this to max 32 entries.
- If there are more, or a new one needs to be added, drop the oldest ones until there are 32 left.
- I've run a simulation with current production entities: for 32 entries, we never exceed 2800 bytes. For 64 entries, we sometimes hit 4500 bytes. For unencoded json, we cannot store more than 20 reliably within 4k bytes.
- It probably makes sense to parametrize this limit, so add a
wayf.remember_choice_per_idp_maxparameter which defaults to 16 to be on the safe side.
- if the cookie content is in any way invalid (invalid base64 encoding, invalid json, etc), log a warning and simply ignore it and remove it from the response.
- The cookie's domain is set to Engineblock's host name
- The
Max-AgeorExpiresproperty of the cookie need to be set in accordance with thewayf.remember_choice_per_idp_lifetimesetting. To reduce complexity, it is not dependent on the actualexpiresvalues in the cookie, so in cornercases (e.g., if thewayf.remember_choice_per_idp_lifetimeis reduced) it might occur that the cookie expires earlier than the individual entries in the cookie. That is acceptable behavior. - The cookie must have
SecureandHttpOnlyproperties (same as all other EB cookies).SameSiteshould probably be set toNonebecause we support both Redirect and POST bindings for SAMLRequests.
-
If this feature is enabled (
wayf.remember_choice_per_idpis set) then do the following when determining whether to show the WAYF:- check if this SP has
coin:wayf_remember_choiceset in the metadata - check If the cookie is present and valid, and if the user is logging in to an SP that is present in the cookie
- check that the SP's
expiryentry is in the future - check that this SP has set
coin:wayf_remember_choicein the metadata - check that this IdP is available for this SP (i.e., it should never be possible for a user to get redirected to an IdP that is not available for this SP based on this cookie only; the cookie only allows a selection for IdPs that are already available).
- if so, then skip the WAYF (like the existing
rememberchoicecookie does). Log if this occurs with level INFO and message "WAYF-remember-my-choice WAYF skipped for because of preselected " - if any of the above checks fail, show the regular WAYF
- check if this SP has
-
Only update the cookie if the user set a new "remember my choice" checkbox. If changes are made, always update the cookie at the client like this:
- remove all expired entries (
timeis older than current time) - remove any entries above the maximum number we support (see above). Drop the oldest ones until we are at the limit. Log if this occurs with level WARNING and message "WAYF-remember-my-choice entities dropped from cookie"
- if no SPs are left in the cookie, remove the cookie altogether
- remove all expired entries (
-
If the cookie is only read and no changes are made by the user, the cookie does not need to be updated.
-
If the users gets the regular WAYF and selects the "remember my choice" checkbox, then do the following if per-SP remembering is enabled (if global remembering is enabled, the behaviour doesn't change):
- Add the selected (SP,IdP) pair the to the cookie with the
expiresfield set tonow + wayf.remember_choice_per_idp_lifetime - Run the checks as specified above
- Set the updated cookie in the response.
- Output a log line with level INFO and message "WAYF-remember-my-choice set for SP and IdP and expiry "
- Add the selected (SP,IdP) pair the to the cookie with the
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with parameters.yml and trace the existing WAYF and global remember-choice flow before designing the per-SP cookie behavior. Implement the feature toggles, metadata check, cookie validation and expiry handling described here; done means valid per-SP selections skip the WAYF only for eligible SPs, while invalid or unavailable selections fall back to the regular WAYF and required logs are emitted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- authentication, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100