Problem/Motivation
Logging in with an IDP worked perfectly until we added some security hardening to the site, like SameSite cookie policy.
After that, we got reports that when a user logs in with the IDP it gets access denied after it is redirected to Drupal. If it refreshes the page or navigates to another one the issue goes away. The page that the user got access denied error was it's profile page because that is the default destination after a successful login. After some debugging, we realized that after the redirection the user is still considered as anonymous until it refreshes the page.
It seems the main issue is the cookies set by the module does not respect the cookie settings of the site, which could include the SameSite cookie policy. Also, the logic inside the controller that handles the authentication and redirection is incorrect in multiple ways. It is hard to follow what it does and why and it probably uses \Drupal::service('page_cache_kill_switch')->trigger() for no reason, which can also lead to unexpected behaviors.
Steps to reproduce
Configure the SameSite policy on a site, set it to Strict or Lax, and try to login via federated login.
Related issues
Possibly related issues that are caused by flaws in the same code.
[#3112851] /saml_login requires anonymous user, but this path is a redirect destination for users logged in through SAML
[#3052206] headers already sent when option "Use Header with: Cache-Control: no-cache" enabled
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | interdiff_3_4.txt | 1.44 KB | mxr576 |
| #4 | simplesamlphp_auth-fix-redirection-issue-3127628-4.patch | 15.24 KB | mxr576 |
Comments
Comment #2
mxr576Having the same issue, this bug appeared after we had enabled the samesite=strict cookie policy.
Comment #3
mxr576Took sime time.... but I think I have managed to find a solution to the problem. I got inspiration from the
\Drupal\comment\Controller\CommentController::commentPermalink().Also, I am not sure what BC promise this module follows, but since Drupal's BC promise also does not cover page controllers, I dared to perform a bigger clean-up on the
SimplesamlphpAuthController.phpbesides the logic fixes that I have made.Hopefully \Drupal::service('page_cache_kill_switch')->trigger(); is not needed anymore, which is a two edged sword...
Please review.
Comment #4
mxr576CS fixes.
Comment #5
berdirHm, that's quite a patch to review. BC is one thing, but it''s quite hard to understand what's just refactoring/improvements and what the actual changes are.
Also, not surprised that samesite strict is causing problems, surprised that anything works with that ;)
Comment #6
mxr576Yeah, I know... :)
The actual change is:
All the other fixes just make the logic more simpler and the code more easier to read and maintain. This is the reason why this one patch could possibly resolve 2-3 other issues in the queue as well.
I also bumped into some early rendering issues - all Drupal devs' favorite one - this is the reason why this is a method and not a property:
and I also thought about PHP >= 7.3 compatibility as you can see - if I have spent hours on this controller :)
(although I must admit that part of the code may require some fine tuning, like parsing the domain and leveraging the samesite option in case of PHP >= 7.3)
Comment #7
mxr576Comment #8
mxr576Comment #9
mxr576Comment #10
mxr576Update: a few months ago we had to change Strict to LAX because everything was working...except when a user open a one time login link in Gmail, Outlook online, etc, s/he could not use it... 🙄 (thanks for the implementation of the one-time login flow)
How can we can we make a step forward with the review of this patch? Are there any active maintainers here?
Maybe PHP 7.3 compatibility bridge could be moved to a new patch since PHP 7.2 is EOL in 2 days and the changed syntax of
setrawcookie()should cause problems to everyone.Comment #11
mxr576It seems there is an another way around to eliminate early rendering issues, although since my added workaround in #4 seems to be working, I am just leaving this here: https://www.drupal.org/project/drupal/issues/2638686#comment-13958570
Comment #12
kekkisI am not sure whether this was your intention @mxr576, but testing e.g. with https://example.com/saml_login?ReturnTo=https://example.com/admin/group renders the contents of /admin/group at the URL https://example.com/saml_login?ReturnTo=https%3A%2F%2Fexample.com%2Fadmi...
- and when I don't have an explicit ReturnTo query parameter defined, I get the site front page at the same URL. This is a bit confusing at least to me. A better way, if possible, would IMO be to redirect the user to the page instead of showing the rendered content of the page at the saml_login route.
Comment #13
dpagini commentedI came across this issue with a similar problem. When my Drupal site is tweaked to only use `SameSite` cookies, this module starts to fail to work for me. It seems to me like the module should have a setting to allow users to turn on the samesite cookie protection when it's setting the cookies...? Following some of the comments, I couldn't quite understand how this relates to redirection...?
I think the comment in #5 may have been asking for a simpler patch that can just fix the issue, or at least that's what I would think this issue needs. Then another issue can be opened up to do some of the refactoring, which can be reviewed independently of this issue. That's what I would suggest here as the best approach to get a patch merged in...
Comment #14
mxr576@kekkis you are right, as far I as I remember that is not an expected side effect, but I do not remember having that issue on the project where the original issue was fixed. The key problem that I tried to solve is not loosing cookie data in given circumstances when redirection happens from the IDP to Drupal.