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

[Feature Request] Backchannel sign-out endpoint to invalidate session #1224

Open
ghuser0 opened this issue Jun 1, 2021 · 47 comments
Open

[Feature Request] Backchannel sign-out endpoint to invalidate session #1224

ghuser0 opened this issue Jun 1, 2021 · 47 comments

Comments

@ghuser0
Copy link

ghuser0 commented Jun 1, 2021

Hi,

To support single-sign-out for Keycloak, in the Keycloak client registration it is possible to specify a backchannel logout URL. If a user authenticated in a realm signs out using any client, keycloak will call this backchannel logout URL for all clients in the realm.

Example

A user has two apps app1.example.com and app2.example.com using oauth2-proxy to secure access using a single Keycloak realm at keycloak.example.com.

The user first visits app1.example.com. They are redirected to keycloak.example.com to sign in. The user signs in and keycloak sets a session cookie, as well as redirects back to app1.example.com/oauth2/callback with an authorization code. oauth2-proxy on app1.example.com creates a session for the user in redis, and sets the oauth2 client cookie to index the redis session.

The user then visits app2.example.com. They are redirected to keycloak.example.com, where they already have a keycloak session cookie. Keycloak keeps the user signed in and automatically redirects back to app2.example.com/oauth2/callback with an authorization code. oauth2-proxy on app2.example.com creates a session for the user in redis, sets the oauth2 client cookie, and the user is automatically signed in after a bunch of redirects with the magic of oauth SSO.

The user now wants to sign out. The user visits app1.example.com/oauth2/sign_out?rd=https%3A%2F%2Fkeycloak.example.com%2Fauth%2Frealms%2Frealm%2Fprotocol%2Fopenid-connect%2Flogout%3Fredirect_uri%3Dhttps%3A%2F%2Fapp1.example.com%2F. app1's oauth2-proxy clears its session, then redirects to keycloak which clears its session, and then redirects back to app1 which is now logged out.

Expected Behavior

When the keycloak logout endpoint is hit, it should use the backchannel logout url of all of its clients to invalidate their sessions. That is, keycloak.example.com should make a backchannel request to app2.example.com to invalidate the user's session. After logging out of app1.example.com, if the user visits app2.example.com, they should be logged out of app2 as well.

Current Behavior

Without a backchannel logout URL in oauth2-proxy, when the user signs out of app1.example.com, the sessions of app1.example.com and keycloak.example.com are cleared, but app2.example.com isn't touched. As a result, if the user later visits app2.example.com, they continue to be logged in.

Possible Solution

A backchannel logout endpoint, that receives a logout token and clears the associated session in redis. This would only work for redis sessions, not cookie sessions, since a backchannel request can't reach in to the user's user-agent to clear cookies.

Your Environment

oauth2-proxy v7.1.3
Keycloak v13.0.1

@ghuser0
Copy link
Author

ghuser0 commented Jun 2, 2021

This seems to depend on:
"Adds ability to validate Logout token"
coreos/go-oidc#251

@ghuser0
Copy link
Author

ghuser0 commented Jun 4, 2021

Hi, I've read in the other issues that single logout is an issue that would be nice to have, but requires thought to implement in a generic way compatible with the identity provider plugin system and not just coupled to OIDC. May I ask for thoughts about the following? I'm no identity expert so please excuse and correct where I get it wrong.

As I wrote in the original issue, single logout can only work when using a backing store (redis being the only one implemented) rather than cookie store, because the backchannel logout response cannot clear the user's cookies. oauth2-proxy (the RP, Relying Party in OIDC speak) would then need to clear sessions in redis based on information extracted from the logout token from Keycloak (the OP, OpenID Provider).

This (draft) OpenID spec (https://openid.net/specs/openid-connect-backchannel-1_0.html) defines the logout token. The pull-request I linked previously adds validation for the logout token similar to the ID token, handling verifying signatures and parsing the json in to a struct. The interesting line as far as connecting the logout token to the redis store is:

"A Logout Token MUST contain either a sub or a sid Claim, and MAY contain both. If a sid Claim is not present, the intent is that all sessions at the RP for the End-User identified by the iss and sub Claims be logged out."

To dig in to the sub / sid distinction and its implications, I should expand my original example to include the following:

Example (pt. 2)

The user has a single identity (subject) with an identity provider (keycloak.example.com), but in addition to securing two applications (app1.example.com and app2.example.com), the user also has two distinct user agents (browser1 and browser2).

The user first visits app1.example.com with browser1. They hit oauth2-proxy (RP), and since they are unauthenticated (no _oauth2_proxy cookie) they are redirected to keycloak.example.com (OP). They provide their username and password, keycloak maps to a subject, creates a session on its side, sets cookies for the OP in browser1, redirects back to RP with an authorization code, which RP trades with OP for access/id/refresh tokens, and then RP creates a session for app1, creates a ticket for that session, stores it in app1's redis, and sets _oauth2_cookie in browser1 for app1.

The user next visits app2.example.com with browser1. They hit oauth2-proxy (RP) in app2 but same as the original example, they don't have the _oauth2_proxy in app2 and so are redirected to keycloak.example.com (OP). The user does have cookies for OP in browser 1, so they are automatically logged in by keycloak, sent back to oauth2-proxy, and automatically logged in. Oauth2-proxy (RP) for app2.example.com sees things exactly the same in this case as RP for app1.example.com did: the user was unauthenticated, sent to the OP, came back with an authorization code, traded for tokens, and RP creates a session for app2, creates a ticket for that session, stores it in app2's redis, and sets _oauth2_cookie in browser1 for app2. It's OP's stored session that enabled the user to stay logged in and not have to authenticate again while hitting app2.example.com for the first time.

In this expanded example, now the user uses browser2 to visit app1.example.com. Browser2 doesn't have any cookies, so the RP sends them to the OP. Because browser2 doesn't have OPs cookies either, keycloak shows a login page. The user provides their username and password. Now OP maps the user to the same subject as has already been logged in, creates a new session for the user in browser2, sets cookies on browser2 and redirects back to RP with an authorization code. RP creates a new session for app1 for the same user/subject, creates a new ticket for that session, stores it in app1's redis alongside the existing session, and sets _oauth2_cookie in browser2 for the ticket for this new session.

The user now signs out using browser2. In browser2 they visit app1.example.com/oauth2/sign_out?rd=https%3A%2F%2Fkeycloak.example.com%2Fauth%2Frealms%2Frealm%2Fprotocol%2Fopenid-connect%2Flogout%3Fredirect_uri%3Dhttps%3A%2F%2Fapp1.example.com%2F. oauth2-proxy clears its cookies for app1 / browser2, redirects to keycloak, and keycloak clears its session and redirects back.

Expected Behavior

The identity provider should be able to choose to log users out of all apps on all user agents. If the user visits app1.example.com with browser1 after logging out using browser2, the identity provider should be able to specify that the user is logged out in browser1 as well.

Current Behavior

Without single logout, the user continues to be logged in for every combination of app / user-agent they previously signed on with, explicitly or implicitly, and have not explicitly signed off with.

Possible Solution

If an identity provider is allowed to perform a backchannel signout, and to support OIDC's ability to sign out a single user session (using the sid claim in the logout token) or all of a user's sessions across all apps and user agents (using the sub claim in the logout token), then something between the SessionStore interface and the redis Client interface needs to be updated. The SessionStore interface looks like it can still work, since it contains Save, Load, and Clear methods that all take in the raw HTTP request as a parameter. That raw HTTP request would include the ID and/or Logout token in addition to the oauth2_proxy cookies.

It seems lots of people continuously want and ask for redis to support multiple keys for a value, see redis/redis#2668 , but that is not implemented. Instead a new index would need to be maintained in redis between subjects and sessions so that all sessions for a subject can be cleared. The index has to be maintained when:

  1. A new session is created for a new subject
  2. A new session is created for a subject that already has an existing session
  3. A session is deleted for a subject that has other sessions
  4. All sessions for a subject are deleted

It looks like the place to put this would be in the persistence manager. Right now the persistence manager translates between tickets and sessions between the HTTP requests and responses. If the persistence manager knew which identity provider was in use, it could ask the identity provider to create a ticket and subject based on the request. In the OIDC case, the ticket could be based on the user's sid claim. The persistence manager would then use the subject to maintain the index of subjects to tickets. The persistence manager's clear method could also ask the identity provider if the request should just clear that session, or should clear all sessions for the subject.

I can see why this isn't trivial, but it would be a really useful improvement. Any feedback is appreciated and I'll keep looking at it, thank you.

@JoelSpeed
Copy link
Member

I think this is an interesting use case, but I don't know how popular of a use case it is. Because of the complexity of the feature, I would like to see a reasonable amount of backing from different users to show that this really is a feature we should invest in maintaining.

I think your analysis is good, and very much appreciated. You are right, we have no way currently to inspect the tickets to understand which to clear. I think this is where we would have the most complexity added as you've already suggested.

This kind of feature and mapping really sounds like we need a relational database rather than redis, implementing this relationship on top of key/values is definitely not going to be fun.

  1. A new session is created for a new subject
  2. A new session is created for a subject that already has an existing session
  3. A session is deleted for a subject that has other sessions
  4. All sessions for a subject are deleted

In some providers, creating a new session for the same OAuth2/OIDC client, clears any existing session already on their side(eg Google), do you think this would cause issues in the model you've described here?

@SeWieland
Copy link

I need this exact feature as well.
I am in the identical situation where I have multiple subdomains, each secured by a separate oauth2-proxy deployment (different clients) and a single keycloak as IdP.

The only workaround to this problem are short expiries and "manual" cookie clrearing. Very annoying..

I think this is a very common case for clusters hosting multiple apps under certain subdomains + Nginx-Ingress. Implementing this feature might be helpful to improve further adoption.

@SeWieland
Copy link

SeWieland commented Jun 16, 2021

As I think it might be of interest, this is a hacky workaround in case of using nignx-ingress (one ingress clearing another ones cookie as well during sign_out).

This will work for two subdomains of example.com (each using a different client).

Pretty nasty:

  • All cookies must be visible on the same root domain (cookie-domain=example.com) (!)
  • Manual configuration should generally be avoided for everythig "auth" IMHO

Part of oauth2-proxy nr. 1 ingress

nginx.ingress.kubernetes.io/configuration-snippet: |
      set $xheader "";

      if ( $request_uri = "oauth2/sign_out" ){
        set $xheader https://example.com/auth/realms/myrealm/protocol/openid-connect/logout;
        more_set_headers "Set-Cookie:  nr2_oauth2_cookie=; Path=/; Domain=.example.com;";
      }

      proxy_set_header X-Auth-Request-Redirect $xheader;

Part of oauth2-proxy nr. 2 ingress

nginx.ingress.kubernetes.io/configuration-snippet: |
      set $xheader "";

      if ( $request_uri = "oauth2/sign_out" ){
        set $xheader https://example.com/auth/realms/myrealm/protocol/openid-connect/logout;
        more_set_headers "Set-Cookie:  nr1_oauth2_cookie=; Path=/; Domain=.example.com;";
      }

      proxy_set_header X-Auth-Request-Redirect $xheader;

This kind of works, but is really ugly. Is there a better way?
"Chaining" the sign_out url redirections will not work because of CORS issues (at least, I did not manage to get it to work).

This could be avoided by beeing able to invalidate the redis session.

Edit: user more_set_headers instead of add_header

@modularTaco
Copy link

I'm also interested in this

@ghuser0
Copy link
Author

ghuser0 commented Jul 7, 2021

Thank you @JoelSpeed and others for having a look. I used to think writing this on key/values was a tragedy, but now I realize, it's a comedy. I'm using this:
ghuser0@f16f9f9
and the dependant PR from coreos/go-idc:
coreos/go-oidc@938b6e9
as patches and although I haven't fully tested this and I'm not an expert in this stack they're working for me so far. I understand the maintainance bar but at least this is a proof of concept. If I get help setting up a test env I can write tests for it.

The abstraction I used on the oauth2-proxy side is 'sign out keys.' Basically, a provider parses sign out keys from the token when creating the session. For OIDC, the spec specifies 'sub' and 'sid' claims in the ID and Logout tokens. I think if an IDP signed out all previous sessions when a subject creates a new session, the IDP would use the previous session's sid claim in its Logout Token. In this abstraction the provider is also responsible for parsing which sign out key to use from the backchannel request. For OIDC the sid claim if present, or sub otherwise. I don't think you support any SAML providers but this seems like it would work with SAML Single Logout too.

In redis, I did all of the index stuff in lua scripts. That seems to be the redis way, each eval is atomic. It's the only way outside external locks, in redis transactions an output of one command can't be used as an input to another. The interface stays mostly stable to redis_store, so it should be easy to swap for a relational DB if you add one in addition or replacement to redis. The nice thing about redis is you get that automatic expiry though which I tried to keep for the indexes.

A couple other design considerations - I made a new endpoint instead of reusing sign_out because the flow through the endpoint, the client that hits it, the use case is all different. If I would have used the same one, the beginning of the endpoint handler would just be trying to figure out how it was called and performing completely different handling in either case. I also considered carying the sign_out_keys as a separate parameter alongside SessionState instead of inside it. The tradeoff here is that the sign out keys have three copies in the database: the original claims they came from, the SignOutKeys field in SessionState, and the s2t: index keys in redis. The copy in SessionState isn't really necessary, but there's a ton of pollution to the API to treat them differently. So they go along for the ride and get pulled out in the persistance manager. Also I treat them as "claims" in the SessionState, but I'm not really sure what claims means in that context, so maybe it'd be better to have a different getter method.

You asked about Google, but I don't think they support single sign out with a backchannel request. They seem to have their Javascript client they expect you to include that does their googly long-poll. If you implemented a polling client in the Google provider, perhaps sign out keys could be helpful if you can dedup those clients together for multiple sessions. I'm using Keycloak which is how I came about this and Azure supports it too. I saw in your other issues you want to have Azure use the OIDC provider and that should work with this too.

As I mentioned I'm using this with Keycloak, and specifically so that I can have multiple applications on multiple servers each using their own oauth2-proxy against the same Keycloak instance and have both single sign-on and single logout working on all of them. To configure this on my Keycloak instance, I just set "Backchannel Logout URL" to "/oauth2/backchannel_sign_out" and then turn "Backchannel Logout Session Required" to Off (so it doesn't include the sid claim in the logout token, since I'm not sending the sid claim in the ID token and I don't want to discriminate between sessions for single logout in my case).

Thanks again and any feedback appreciated.

@aledt
Copy link

aledt commented Aug 2, 2021

I think this is an interesting use case, but I don't know how popular of a use case it is. Because of the complexity of the feature, I would like to see a reasonable amount of backing from different users to show that this really is a feature we should invest in maintaining.

Just to add a voice to this - we're also very interested in this. We're using Keycloak to secure multiple applications and we're looking at this exact scenario.

@crumohr
Copy link

crumohr commented Aug 10, 2021

We are interested in this as well!

@JoelSpeed
Copy link
Member

I've had a look through the patch and for the most part it looks good. Couple of questions and bits I'd like some clarification on.

  • Is the go-oidc patch merged now? Is there a PR we can track if not?
  • Why exactly are we using Lua scripts? Can this not be achieved natively in go? Is there some particular benefit to using Lua here?

Otherwise I think it looks pretty good, I think the decision to create a separate backchannel sign out endpoint makes sense

@ghuser0
Copy link
Author

ghuser0 commented Aug 30, 2021

Hi,

The go-oidc patch is not merged, it is in PR at coreos/go-oidc#251 . There hasn't been discussion on the PR about timeline for merging, but it's possible they are waiting for "OpenID Connect Back-Channel Logout 1.0 - draft 06" to turn in to final form. I can sit on this patch and use it locally for now until that happens or I can ask around for a timeline for the dependencies if you'd like.

The reason I'm using Lua scripts to maintain the indexes in Redis is for atomicity. As it stands, multiple instances of oauth2-proxy can connect to and share the same Redis database. Without atomicity, the indexes could become inconsistent if multiple requests occurred simultaneously, or even if a single request was in-progress when the oauth2-proxy process failed or was killed. Redis transactions, which are surfaced in the Go library, cannot work for this maintenance because of a limitation where an output from a Redis command inside a transaction cannot be used as the input to a subsequent command in the same transaction. I need that to, for example, update the sign out key indexes when a ticket is being cleared because I need to use the ticket id to look up the sign out keys the ticket is a member of, and then access those sign out keys to remove the ticket id.

Even if I built a separate semaphore system to prevent multiple instances of oauth2-proxy from accessing the database at the same time, I would still need to handle the case of a client dying in the middle of index maintenance. Lua scripts in Redis EVAL operate completely atomically and block other commands. It's important to pay attention to algorithmic complexity of the operations in Redis Lua scripts, but there shouldn't be much overhead caused by using EVAL itself.

There are a couple of things I'd like to do to the patch before turning it in to a PR:

  • Rebase it
  • I would remove the handling in the Azure provider, since you're deprecating the Azure provider for the OIDC provider I would rather just implement there. I don't like how I copied verifyTokenExtractSignOutKeys from verifyTokenAndExtractEmail. Implementing the Azure provider showed me how this works with other providers as well.
  • I would like to write and run tests, I would like help please getting started running tests in my dev env.

Thanks again.

@ghuser0
Copy link
Author

ghuser0 commented Sep 1, 2021

This issue #1346 is also relevant to the question of when to bring this change in. It might make sense to bring it in on a major version with a call-out that older instances of oauth2-proxy should not use the same Redis database as instances after this change is introduced.

@wadahiro
Copy link
Contributor

@ghuser0 @JoelSpeed

I too would like to see the backchannel logout feature implemented 😄

By the way, I have come up with a couple of ways to implement with different approaches to ghuser0/oauth2-proxy@f16f9f9. I'd love to hear your thoughts on this.

  • A) Use the sid claim of the ID token as the session key to store in Redis.
  • B) Use the sid or sub claim in the logout token as the key to store the blocklist in Redis.
  • C) Hybrid method of A and B

Approach A

Currently,oauth2-proxy generate random bytes for the session key to be stored in Redis. Instead, we use the sid claim of the ID token (or hash the value of the sid) for the key.

  • Pros
    • Does not require extra Redis space.
    • Implementation can be very simple
  • Cons
    • Backchannel logout with sid is possible, but logout with sub is not supported.

Approach B

Instead of immediately deleting the corresponding data from Redis upon receiving a backchannel logout request, store it in Redis as a block list.

  • Example keys: _oauth2_proxy-<sid> and _oauth2_proxy-<sub>
  • The value should be the iat claim of the logout token.

Then, when oauth2-proxy receives a request from a browser, it will check if it corresponds to the block list. iat claim value is stored, so that only sessions created before it will be blocked.

  • Pros
    • Can support logout using sub as well as sid.
  • Cons
    • Consume extra Redis space (but only if backchannel logout is performed).

Approach C

Hybrid of approaches A and B. Use approach A for logout with sid and approach B for logout with sub.

  • Pros
    • Can be used to logout using sub as well as sid.
    • Unlike Approach B, there is no need to add a blocklist for sid to Redis.
  • Cons
    • Both approaches need to be implemented.

As a PoC, I've tried to implement Approach C. I would appreciate your feedback. Thanks!

@FlxPeters
Copy link

Nice to see this is already an issue. We also have this demand. We deploy a proxy as sidecar to most of our services. A single log out using backchannel logout would be a huge improvement.

@ghuser0
Copy link
Author

ghuser0 commented Nov 18, 2021

Thanks all, and thank you @wadahiro for the other approach and PoC! The blocklist is an interesting idea and if it can avoid the Redis Lua it could be easier to maintain.

I think there is a danger in comparing the session's CreatedAt value to the logout token's IssuedAt claim at https://github.com/openstandia/oauth2-proxy/blob/800cd16402c12364fdc36744d0656b25f8d6f762/pkg/middleware/stored_session.go#L105 . If the clocks of the OP and RP aren't perfectly synchronized, the OP might issue a backchannel sign out with an IssuedAt claim that is before the CreatedAt time of the stored session. The backchannel sign out would then complete successfully with 200, but the session would still continue to validate. If the clocks were off by a minute, the user signed on, did quick work, signed off, the sign out could appear to succeed but the session would continue to validate in subsequent requests.

@ghuser0
Copy link
Author

ghuser0 commented Nov 21, 2021

Could that be replaced with a monotonic counter in the redis database? That could give you ordering between session creations and sign outs. I think you could share a single counter that is incremented for every created session and every created signed out user in the blocklist.

https://redis.io/commands/INCR

@rperpe
Copy link

rperpe commented Dec 28, 2021

I would also like to express need for this feature.

@alexisgaziello
Copy link

alexisgaziello commented Feb 9, 2022

Hey,

I was also looking for some functionality as described here and in 1368.

I am not an expert in Nginx, and @SeWieland solution wasn't working for me. That config didn't make any change. However, it did help to create the following solution below. My setup uses the OAuth2 proxy in Kubernetes, so I just added the following to my ingress:

  nginx.ingress.kubernetes.io/configuration-snippet: |
    location /sign-out {
        rewrite ^/sign-out(.*)$ /oauth/sign_out?rd=https://www.oidc-provider.example.com/signout$1 redirect;
    }

Note: The $1 may be unnecessary functionality. It just takes whatever was written after /sign-out and adds it to the new URL. Feel free to remove it.

Essentially, this solution is creating a new endpoint that constructs the oauth2 signout endpoint with custom logic.

You can even go one step further and add the redirect_uri from your logout provider and complete the cycle. In my case it was Keycloak, and I wanted to show the original app and restart the login process. But you can change that and add a logout confirmation page or similar.

    nginx.ingress.kubernetes.io/configuration-snippet: |
      location /sign-out {
          rewrite ^/sign-out(.*)$ /oauth/sign_out?rd=https://www.oidc-provider.example.com/signout?redirect_uri=https://original-app.example.com redirect;
      }

One step further:

I am using Helm to deploy all of this, so I am constructing the URL dynamically with the values.yaml file:

    nginx.ingress.kubernetes.io/configuration-snippet: |
      location /sign-out {
          rewrite ^/sign-out(.*)$ /oauth2/sign_out?rd={{ .Values.oauth2.OIDCIssuerURL }}{{ .Values.oauth2.OIDCIssuerLogoutPath }}{{ .Values.oauth2.OIDCIssuerRedirectOption }}http://{{ .Values.ingress.host }} redirect;
      }

One more side note:

I believe that there are multiple ways of creating this new endpoint. I looked into using something like

      location /sign-out {
          return 30X new-url
      }

But I didn't know which 30X code would be more appropriate nor wasn't sure it would be better, so I just went with the initial approach.

Hope this helps.
Best,

@alexisgaziello
Copy link

alexisgaziello commented Feb 9, 2022

Actually, I talked too fast. There seems to be a small caveat.
Right now, if you sign-out with this process, and access the original host again, my browser is giving me a cached version of the web-app so it appears that I am still logged in. I will see if I can fix this somehow.

EDIT:
adding more_set_headers "cache-control: no-cache";just before location solves the problem. however, if this is disabling cache for all the web-app, it's definitely not a ideal. HTTP doc says that this option just tells the browser to validate cache before using it, so it should be good.

@github-actions
Copy link
Contributor

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

@github-actions github-actions bot added the Stale label Apr 12, 2022
@aslafy-z
Copy link
Contributor

Un-stale please

@JoelSpeed JoelSpeed removed the Stale label Apr 12, 2022
@SeWieland
Copy link

SeWieland commented Apr 21, 2022

@alexisgaziello I tried yet another way and it works indeed quite well for me!

I'm adding the following annotations to my oauth2-proxy ingress:

ingress:
  enabled: true
  path: "{{ .Values.oauth2.ingressPath }}"
  hosts:
    - "{{ .Values.domainName }}"
    - "{{ .Values.subDomain1 }}.{{ .Values.domainName }}"
    - "{{ .Values.subDomain2 }}.{{ .Values.domainName }}"
    - "{{ .Values.subDomain3 }}.{{ .Values.domainName }}"
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/enable-global-auth: "false"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      set $xheader "";
      if ( $request_uri = "{{ .Values.oauth2.ingressPath }}/sign_out" ){
        set $xheader https://{{ .Values.domainName }}/auth/realms/{{ .Values.keycloak.realm }}/protocol/openid-connect/logout;
      }
      proxy_set_header X-Auth-Request-Redirect $xheader;

ect..

It does not overwrite the whole location block, but just adds the correct redirect header on sign out.
This actually solved all issues I had for me.

Actually I gave up on maintaining 2 separate proxies and am just using a single one now.

@SeWieland
Copy link

I think this issue is linked to #884 as well.
Since KC v18 the above solution does not work for me anymore.

@chuegel
Copy link

chuegel commented Aug 19, 2022

We are also very interested in this. As mentioned above, the solution doesn't work with KC > 18 anymore.

@github-actions
Copy link
Contributor

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

@github-actions github-actions bot added the Stale label Oct 19, 2022
@JoelSpeed JoelSpeed removed the Stale label Oct 19, 2022
@github-actions
Copy link
Contributor

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

@github-actions github-actions bot added the Stale label Aug 24, 2023
@aslafy-z
Copy link
Contributor

This is still desired

@github-actions github-actions bot removed the Stale label Aug 26, 2023
@shkarface
Copy link

This is still desired

@Montralis
Copy link

Montralis commented Sep 20, 2023

We are also very interested in this partikular feature. Is using redis a possible tmp solution for this?

@Math-Lang
Copy link

Interested as well. Logging using the /oauth2/sign_out with a redirect to keycloak signout page works partially fine. When going back app1.example.com, i am able to connect and only get intercepted by the login page after refreshing the page.

@smokeythebandit
Copy link

Would also really like to see this feature.

@AndreLobato
Copy link

Looking forward for this feature as well!

Copy link
Contributor

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

@github-actions github-actions bot added the Stale label Apr 30, 2024
@simaotwx
Copy link

Issue is still relevant.

@github-actions github-actions bot removed the Stale label May 2, 2024
Copy link
Contributor

github-actions bot commented Jul 1, 2024

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

@github-actions github-actions bot added the Stale label Jul 1, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jul 9, 2024
@aledt
Copy link

aledt commented Jul 10, 2024

This issue is still relevant

@andoks
Copy link

andoks commented Jul 18, 2024

@JoelSpeed : should this issue be reopened to signal that Backchannel sign-out still is a possibility?

@tuunit tuunit reopened this Jul 18, 2024
@tuunit tuunit changed the title Backchannel sign-out endpoint to invalidate session [Feature Request] Backchannel sign-out endpoint to invalidate session Jul 18, 2024
@babs
Copy link
Contributor

babs commented Aug 19, 2024

Isn't #1876 the solution ?

@simaotwx
Copy link

Isn't #1876 the solution ?

No, that's the URL that oauth2-proxy would call to perform the back channel sign-out on the IdP, but this issue is about providing an endpoint in oauth2-proxy that the IdP would call to invalidate the user session in oauth2-proxy.

@babs
Copy link
Contributor

babs commented Aug 19, 2024

Hummmm sorry for the misunderstanding ;)

@broekema41
Copy link

I would just like to add some more context. Due to cross domain cookie restrictions in Firefox and Safari it is becoming as good as impossible to provide customers with a multi client logout experience. Most IDP's are advising to do back channel logout as per the spec. invalidating session (access and refresh tokens attached to a session) in a backend store.

The backchannel logout is has become a official spec in 2023 no longer a draft specification
https://openid.net/specs/openid-connect-backchannel-1_0.html

references:
https://backstage.forgerock.com/docs/idcloud/latest/am-oidc1/backchannel-logout.html
https://auth0.com/docs/authenticate/login/logout/back-channel-logout
https://www.keycloak.org/docs/latest/release_notes/index.html#openid-connect-back-channel-logout

kind regards, Roland

Jing-ze pushed a commit to Jing-ze/oauth2-proxy that referenced this issue Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests