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

SAML url doesn't seem to play well with add_trailing_slash #57

Open
mandrew opened this issue Feb 27, 2024 · 1 comment
Open

SAML url doesn't seem to play well with add_trailing_slash #57

mandrew opened this issue Feb 27, 2024 · 1 comment

Comments

@mandrew
Copy link

mandrew commented Feb 27, 2024

Hi, we have noticed an issue when setting the yml config add_trailing_slash: true with our setup. (https://docs.silverstripe.org/en/5/changelogs/5.0.0/#trailing-slash)

We have a slightly custom setup (https://github.com/silverstripe/silverstripe-saml/blob/main/docs/en/developer.md#create-your-own-saml-configuration-for-completely-custom-settings) that simply sets the SAML url to "$[ID] . saml/url-goes-here"

In live mode SAML returns an error:
[Unknown Error] [SAML-65dd445b59f81] [code: 8] SAML Response not found, Only supported HTTP_POST Binding (/var/www/mysite/.../vendor/onelogin/php-saml/src/Saml2/Auth.php:258)
GET /saml/url-goes-here/
Line in
Trace

After scratching our heads for a while, removing the add_trailing_slash config made it work again. Setting the config below seems to fix the issue, however we think this should be better dealt with in the module?

SilverStripe\Core\Injector\Injector:
  SilverStripe\Control\Middleware\CanonicalURLMiddleware:
    properties:
      enforceTrailingSlashConfigIgnorePaths:
        - 'saml/url-goes-here'

Also open to any better config that we might have missed :)

@mandrew mandrew changed the title SAML url doesn't seem to play well with add_trailing_slash out of the box SAML url doesn't seem to play well with add_trailing_slash Feb 27, 2024
@NightJar
Copy link
Contributor

NightJar commented Nov 6, 2024

Kia ora @mandrew

Background

I've just tested to confirm a suspicion locally - the new trailing slash feature feature forces a site to use one or the other - when the "wrong" version is loaded a 301 Moved Permanently is issued redirecting the browser to the "correct" version.

By default that is

> GET /some-page/
< 301 Location: /some-page
> GET /some-page
< 200

And the opposite for add_trailing_slash: true

> GET /some-page
< 301 Location: /some-page/
> GET /some-page/
< 200

This fails with SAML Responses as POST is usually dropped when performing a redirect (GET is usually used on the new location instead).
https://www.rfc-editor.org/rfc/rfc9110#status.301

In contrast to either of the add_trailing_slash options, the old functionality was a third option; to not care.

> GET /some-page
< 200

or

> GET /some-page/
< 200

This third option is obtainable for the entire site by either configuring it to not apply, or perhaps by including / as an ignore path. You've excepted just the one critical path for SAML, which I think is actually probably the best solution in this case 👌

SilverStripe\Core\Injector\Injector:
  SilverStripe\Control\Middleware\CanonicalURLMiddleware:
    properties:
      enforceTrailingSlashConfig: false

or

SilverStripe\Core\Injector\Injector:
  SilverStripe\Control\Middleware\CanonicalURLMiddleware:
    properties:
      enforceTrailingSlashConfigIgnorePaths:
        - '/'

The latter should work as the assessment is done via str_starts_with
https://github.com/silverstripe/silverstripe-framework/blob/d871f4067b0935df0c1d728a649b8cdf411efeb4/src/Control/Middleware/CanonicalURLMiddleware.php#L415

Your specific use case

The example you've used in your issue description is obviously edited, so it's hard to say. But if the formatting is still in exactness, one of two things is happening:

  • The response URL is set without the trailing slash, causing the redirect to happen (i.e. your configuration doesn't match your Silverstripe configuration - both of which are values you control) - i.e. compare the discrepancy between add_trailing_slash: true and AssertionConsumerServiceURL="/saml/acs" (where /saml/acs should be /saml/acs/ in this case)
  • The response URL is set correctly, and it is getting reformatting somewhere to exclude the trailing slash before being used to direct the browser there.

As above I think your solution is probably the best one. What remains for this issue is for that troubleshooting process to be documented.

I've been investigating this topic as it has caught me out too with an upgrade from CMS 4 to CMS 5 with the extra_acs_base feature. In my case my configuration included trailing slashes that I had to delete, as the Director::absoluteBaseUrl() they are compared against no longer has a trailing slash (running with the default setup).

https://github.com/silverstripe/silverstripe-framework/blob/d871f4067b0935df0c1d728a649b8cdf411efeb4/src/Control/Director.php#L893

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

No branches or pull requests

2 participants