When user logs in through the provider, should also inform provider when he wants to logout.
I am setting this as a bug for the following simple reason.
- User 1 sits on the computer
- User 1 login thought the OAuth2 Server provider and gets auto redirected in the page
- User 1 does his stuff
- User 1 wants to logout, clicks log out
- User 1 thinks he can leave his station, as he has logged out
- User 2 sits on the computer
- User 2 clicks to log in through the OAuth2 Server
- User 2 gets auto redirected logged in as User 1.
In theory, this is solved by OpenID Connect Extras ( https://www.drupal.org/sandbox/antrecu/2475233 ) but it is not. It stores access tokens for all users within the same variable, destroying also basic settings. Also, this should be implemented within the Generic client by default (patch is on the way).
| Comment | File | Size | Author |
|---|---|---|---|
| #31 | openid_connect-logout-support-2882270-31.patch | 6.96 KB | jibus |
| #27 | openid_connect-logout-support-2882270-26.patch | 6.96 KB | romanos |
Issue fork openid_connect-2882270
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
xaris.tsimpouris commentedIt's not ideal, but it's a start. Some credit goes also to OpenID Connect Extras for taking ideas.
Comment #3
pjcdawkins commentedThis should use OAuth 2.0 Token Revocation, rather than a browser redirect, where possible:
https://tools.ietf.org/html/rfc7009
Comment #4
mranthony commentedAlso interested in this as an added feature.
We have a situation where multiple users could be logging in from a the same computer and accessing as the previous user.
Following.
Comment #5
nrogers commentedAs far as I can tell token revocation does not appear to be supported by the provider I intend to use this with (OpenID Connect Windows AAD), so in this case I think a redirect is acceptable. The #1 patch works for me, a caveat being the need for the endSession function to exist for additional providers. I modified the patch to check for the endSession function in the provider first and leave an error message in the log if it doesn't support it. The endSession function for the generic provider may need modified as I'm not using it so I did not test.
Note: This breaks the masquerade module, have to add some hackery in to check if called by the masquerade module to skip the logout hook if you want masquerading to work.
Comment #6
solideogloria commentedThis patch improves upon #5, because it fixes the masquerade issue mentioned in this issue, as well as fixing an issue with Azure AD on logout (there was a php error because the tokens did not exist in the $_SESSION variable). Tokens are not used on Azure AD, so a check needs to be added to prevent PHP errors on logout in that case.
Comment #7
solideogloria commentedComment #8
robin.ingelbrecht commentedNvm
Comment #9
solideogloria commentedI've been using patch #6 in production for nearly an entire year, and I haven't had any issues.
Comment #10
jcnventuraI've now committed #2559543: Add pre_login hook similar to post_authorize hook, which this patch is duplicating. This needs to be re-rolled without that code. Note that the committed code uses
hook_openid_connect_pre_authorizeComment #11
narendra.rajwar27Comment #12
narendra.rajwar27Patch updated as mentioned in comment #10.
Comment #13
solideogloria commented#12 works for me when applied to dev when not masquerading.
One thing I noticed, however, is that if I visit /user/logout while masquerading, it looks like it is logged out, showing the anonymous front page, and clicking any page will act like I'm not logged in, but if I then click to log in or visit the login link, I'm instantly authenticated (as the parent user, not the user I was masquerading as), bypassing login. If this is an edge case that doesn't need to be handled then it's fine (after all, I normally replace the login button for people masquerading with a button to stop masquerading).
I have not tested if it behaves this way without the patch.
Comment #14
dcam commentedI don't think that the session should be destroyed here. Other implementations of hook_user_logout() that run after this might rely on session data. Also, the session gets destroyed in user_logout_current_user() immediately after all of the logout hooks run, so it seems unnecessary. I could provide a patch, but I don't have a convenient way to test it myself because I'm only consulting for someone else who is using this module and patch.
Other than that, the patch is working well for us. We don't use Masquerade, so I'm choosing not to comment on whether the issue mentioned in #12 is an edge case or not.
Comment #15
solideogloria commentedRemoving
session_destroy();here completely prevents effective logout. On redirect after logout, it will be as if no logout occurred, with the user still logged in, despite the watchdog message showing theuser_logout_current_user()function ending the session.I tried testing without it, as well trying setting the session global variable to an empty array instead, but neither works. All I had to do to test this was change the code and log in and out with SSO.
If it's necessary, the module could alter the order of hook implementations to ensure this hook is called last.
Comment #16
dcam commentedThank you for testing my suggestion, @solideogloria. I appreciate the assistance. Based on your description I see what's happening. The patch uses
drupal_goto()to redirect the user.drupal_goto()callsdrupal_exit(), which interrupts the execution. So yeah, the session is never destroyed byuser_logout_current_user(). Sessions would have to be destroyed in this hook or we would have to not use redirects for logging out, which sounds like it's impossible in some cases.By the way, this also means any
hook_user_logout()implementations that are executed after this one get skipped entirely. So it's potentially a bigger problem than the session data simply being unavailable to them. @solideogloria is right, this could require adjusting the module weight.Comment #17
solideogloria commentedActually the watchdog line in
user_logout_current_user()is still called (I see the message in the dblog), so I don't think we're preventing execution of other code...Comment #18
solideogloria commentedRe: #13, after looking at masquerade.module, I decided that's (kind of) the intended behavior. Clicking to log out while masquerading logs out the masqueraded user and does not affect the parent user in any way:
This begs the question about whether the following code should even be included in the patches, since if I'm right, then the user should/would be logged out:
However, the patch is working well as-is for me. If nobody has any objections, I'm going to mark it RTBC. The above could always be put as a separate issue.
Comment #19
solideogloria commentedRemoved unused
global user;Comment #20
solideogloria commentedComment #21
solideogloria commentedI reviewed this again during the process of creating a patch to support logout for OpenID Connect Microsoft Azure Active Directory client, and I updated the URLs in a comment.
Comment #22
solideogloria commentedRealized that @see comments should come after @param comments.
Comment #23
solideogloria commentedComment #24
solideogloria commentedI realized that the base class and interface should match this change.
Comment #25
solideogloria commentedRerolled.
Comment #26
solideogloria commentedComment #27
romanos commentedre-rolled for tag: 7.x-1.0
Comment #28
solideogloria commentedThe patch in #27 applies and the resulting code changes are the same as the previous patch.
If someone else will review, this could be RTBC.
Comment #29
colanIs this also a problem in the 3.x branch?
Comment #30
sanduhrsSince September 12, 2022 there is an official spec for this.
See https://openid.net/specs/openid-connect-rpinitiated-1_0.html
Comment #31
jibus commentedre-rolled against current 7.x-1.x
Tested with Auth0 and worked.
Comment #32
solideogloria commented@colan No, logout is supported in 3.x
Comment #35
marvil07 commented@xaris.tsimpouris, thanks for starting this!
And to everyone in the thread that pushed it forward.
I have been trying the latest iteration at #31, and it seems to work OK 👍
I have iterated over it, and added some changes on top, but first, let me reply a bit to previous comments.
The comment at #16 is quite relevant:
⚠️ In other words, using this patch also means that the site may need to adjust the module weight for this module, so it runs at the end of the set.
There seems to not be a way around it, since a redirect is quite definitive.
Re #17: The watchdog message happens before invoking the hooks, hence it will appear at the start.
E.g. if module A and
openid_connectare implementinghook_user_logout(), and theopenid_connectmodule gets called first, theA_user_logout()hook will not be run.Re #30: Yes.
Looking into the way this works, and the spec about Relying Party initiated logout linked, I think these changes actually implement it.
On masquerade module support, I added a check to verify if the module is there on the related code, since it may not be there.
I have also added the client identifier as parameter on the redirect, which is part of the optional parameters to pass on the spec, and will add an extra hint to the IdP that will produce an extra check.
Also, I have been trying to avoid the persistence of the token data into the session, but I could not arrive to a working solution.
I even tried to use the internal mechanism for redirect, but I could not make it work, basically the following hunk.
Ideas are welcome about how that may be possible.
In the mean time, I restricted this to only the
token_id, since that is the only consumed piece.I opened a
2882270-logout-supporttopic branch and related new MR !107 with the following commits.Comment #36
drummRather than module weighting,
hook_module_implements_alter()is a bit nicer to control hook ordering, in case some hooks need to fire early and others late.Comment #37
marvil07 commented@drumm, that makes sense.
I have added an implementation of that hook moving the new
hook_user_logout()to be executed at the end.New commits on the
2882270-logout-support topicbranch and related MR !107:- 56dfedf Move hook_user_logout implementation to the end of the set
Comment #38
heddnI've done a code only review of the latest MR. It looks in order. I hesitate to mark RTBC since I haven't manually tested it.
Comment #39
drummLooks good to me too. We will be running this on Drupal.org’s codebase.
Comment #40
drumm