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

Add support for front-channel OIDC logout #105

Open
anderius opened this issue Oct 29, 2024 · 6 comments
Open

Add support for front-channel OIDC logout #105

anderius opened this issue Oct 29, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@anderius
Copy link

The current implementation relies on cookies for front-channel logout. As noted in the spec, this is increasingly problematic, as modern browsers will not send cookies with content in an iframe.

The solution is either to use back-channel logout (which my IdP does not support), or use the sid parameter from the id-token as a session identifier, as is optional in the spec.

My feature request is that this oidc-implementation supports the sid parameter for front-channel logout.

@anderius anderius changed the title Support sid parameter for frontchannel logout Support sid parameter for front-channel logout Oct 29, 2024
@route443
Copy link
Contributor

route443 commented Nov 3, 2024

As I understand it, what you are asking for is a front-channel logout implementation, but we support only RP-initiated OIDC logout (see PR #96 ). The difference is that in the case of front-channel logout, the initiator is the IdP, and logout is performed through an iframe mechanism, relying on sid rather than authentication cookies (auth_token). I think we could add support for both back- and front-channel logouts, but it might be quite challenging, as we currently use auth_token as the key for tokens, and obtaining cookies based on, say, sid is not feasible. I’ll think about what can be done.

@route443 route443 added the enhancement New feature or request label Nov 3, 2024
@route443 route443 changed the title Support sid parameter for front-channel logout Add support for front-channel OIDC logout Nov 3, 2024
@anderius
Copy link
Author

anderius commented Nov 4, 2024

@route443 Our initial idea was to create a keyval map on login, from sid to auth_token. Then we could fetch auth_token from sid on logout, and create a sub-request with auth_token set. Would that not work?

@route443
Copy link
Contributor

route443 commented Dec 4, 2024

As far as I understand, technically, we cannot create a mapping like this:

keyval $foo $bar  
keyval $bar $baz

because if foo is an empty string, then baz will also be an empty string. However, nothing prevents us from setting up a mapping like this:

keyval $cookie_auth_token $session_jwt  
keyval $idp_sid $client_sid

where client_sid will equal cookie_auth_token. The issue is that, ultimately, we need to define the cookie_auth_token var, and doing this via a r.subrequest is not feasible because we cannot add headers to the client request (only args or body). We could use proxy_set_header, but that would require a proxy_pass.

I have an idea of how this could be implemented, but the solution requires refinement...

Question: whether you use only sid or sid + iss, as the spec requires both args to be present (since the uniqueness of sid can only be guaranteed within the scope of a single OP).

@anderius
Copy link
Author

anderius commented Dec 6, 2024

We will get both, so the map should then maybe include them both concatenated?

Example:

GET https://client.example.com/myapp/logout
     ?iss=https://idporten.no/
     &sid=D8Fgz-jEXG7JXP_VAORmAm1sKB0LjZyA3wAy-rVyMYc=

Source in Norwegian for reference: https://docs.digdir.no/docs/idporten/oidc/oidc_func_sso.html#2-h%C3%A5ndtere-utlogging-fra-id-porten-front-channel-logout

@route443
Copy link
Contributor

route443 commented Dec 6, 2024

I’d prefer to avoid using keyval as much as possible, primarily because it complicates the config and, secondarily, due to memory consumption and potential sync overhead. The current implementation (POC) uses a slightly different approach: since we can derive the auth_token from the op sid, and => the auth_token -> id_token, we can extract the iss and validate it against the one received from the args.
Additionally, this approach opens the way for back-channel logout, where based on the sid from the logout_token, we can retrieve all the necessary vars to clean up the session state.

@route443
Copy link
Contributor

Hi @anderius ,

I've added support for Front-Channel logout in a separate oidc-logout-handling branch. I would greatly appreciate if you could check these changes in your environment and provide any feedback.

You can use openid_connect.js from this branch and make the following changes to your config:

  1. For openid_connect_configuration.conf, add:
keyval_zone zone=oidc_sids:1M state=/var/lib/nginx/state/oidc_sids.json timeout=8h;
keyval $idp_sid $client_sid zone=oidc_sids;
  1. For openid_connect.server_conf:
  • Add the variable:
set $idp_sid "";
  • Update the /_id_token_validation location to /_token_validation.

  • Add a new location to handle Front-Channel requests:

location = /front_channel_logout {
    status_zone "OIDC logout";
    add_header Cache-Control "no-store";
    js_content oidc.handleFrontChannelLogout;
}

Thank you in advance!

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

No branches or pull requests

2 participants