Problem/Motivation
When using a multilingual site using domain detection, line 326 of openid_connect/src/Controller/OpenIDConnectRedirectController.php
$redirect = Url::fromUri('internal:/' . ltrim($destination, '/'), ['language' => $language])->toString();
throws an invalid argument exception.
"The internal path component
is external. You are not allowed to specify an external URL together with internal:/."
This happens due to the URL being saved to the session data "openid_connect_destination" in OpenIdConnectSession::saveDestination method, being generated as an absolute URL when processed via LanguageNegorationUrl::processOutbound.
UrlHelper::isExternal is flagging this as external and an exception is thrown.
Steps to reproduce
Add a language and set URL detection to domain and add the domain and an alternative.
Add the OpenIDConnectLoginForm to a page and attempt to login via the form.
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | 3478572-3.patch | 1.08 KB | j-lee |
Issue fork openid_connect-3478572
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
j-leeCurrently it is line 350.
But it is hard to test without the multi-domain language setup in Drupal.
What is provided in
$destination? Something like https://my-language-domain.example.com?Maybe, we can check if
$destinationis an external url and than remove the'internal:/':Comment #3
j-leeI have attached a patch file for initial review/testing before I create an MR.
Comment #6
pfrillingI refactored the destination redirect logic into it's own method and added some validation to confirm if it is external and to confirm it is of the local domain.
I tested with the login block and domain based language detection and all seems to be working correctly.
Comment #7
benjifisher@pfrilling:
The changes for this issue are a little complicated, and I will need at least two rounds of review to understand them well. For this first round of review, I made some low-level suggestions on the MR.
Comment #8
benjifisherI have the same question as in Comment #2:
I think this question should be answered in the "Steps to Reproduce" section of the issue summary.
As I said on the merge request, I do not see how the current version will fix the problem if
$destinationis something likehttps://de.example.com/some/page.@pfrilling:
In Comment #6, you wrote,
Can you say a little more about how you tested? What
destinationparameter(s) did you try?Comment #9
pfrilling@benjifisher, I updated the MR with your feedback and addressed some of the comments there.
I tested locally by:
- enabling language negotiation with a subdomain and added a subdomain as a FQDN within ddev.
- placing the login block provided by the module.
- Browsing to `node/1` and clicking login either in the default language or the subdomain, which provided the absolute url as the destination.
I also added an absolute url as the `redirect_login`, which was throwing in certain scenarios. That is why I used `` as the fallback within that method.
Comment #10
benjifisherI wonder if the change can be simplified either because Drupal core already sanitizes the
destinationquery parameter or because we can borrow some of the code it uses to do that.I asked Claude AI how Drupal core handles the
destinationquery parameter. I am dumping the response here until I have time to validate it and see whether it can help: