X Tutup
Skip to content

Allow SP initiated Artifact binding#2412

Draft
monkeyiq wants to merge 1 commit intosimplesamlphp:simplesamlphp-2.4from
monkeyiq:2025/march/artifact
Draft

Allow SP initiated Artifact binding#2412
monkeyiq wants to merge 1 commit intosimplesamlphp:simplesamlphp-2.4from
monkeyiq:2025/march/artifact

Conversation

@monkeyiq
Copy link
Contributor

If this block is in use then the SP will send an art request using the binding to the IdP which will fail. It seems the request from the SP to the IdP must be a normal redirect but with the special artifact attribute to indicate to the IdP that the login should be processed using an artifact.

Without this explicit elseif block an AuthnRequest will be delivered normally to the IdP and will still have the artifact attribute. The successful SAML login will see a GET with an art and in the samltracer you don't get to see the response because it is happening in the background between the SP and IdP.

For example:
GET https://FQDN/sspsmall/module.php/saml/sp/saml2-acs.php/default-sp?SAMLart=AAQ

This relates to a recent discussion on the mailing list with topic "Using artifact binding with simplesamlphp SP and IdP".

If this block is in use then the SP will send an `art` request using the
binding to the IdP which will fail. It seems the request from the SP
to the IdP must be a normal redirect but with the special artifact
attribute to indicate to the IdP that the login should be processed
using an artifact.

Without this explicit elseif block an AuthnRequest will be delivered
normally to the IdP and will still have the artifact attribute. The
successful SAML login will see a GET with an `art` and in the samltracer
you don't get to see the response because it is happening in the
background between the SP and IdP.

For example:
GET https://FQDN/sspsmall/module.php/saml/sp/saml2-acs.php/default-sp?SAMLart=AAQ
@monkeyiq
Copy link
Contributor Author

monkeyiq commented Apr 9, 2025

I am testing this on sspsmall which I have upgraded to SSP 2.3.7. Testing in the admin interface and the Test tab.

I have set default-sp to be an SP which wants to communicate with the same install of SSP as an IdP.

As per the documentation (https://simplesamlphp.org/docs/stable/simplesamlphp-artifact-sp.html) I have set the SP to have the ProtocolBinding of HTTP-Artifact in config/authsources.php

    'default-sp' => [
        'saml:SP',
        'entityID' => 'https://sspsmall.example.org/',
        'idp' => 'urn:x-simplesamlphp:sspsmall-idp',
        'ProtocolBinding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact',
        'privatekey' => 'sp.example.org.pem',
        'certificate' => 'sp.example.org.crt',
    ],

The expected behaviour here is to be able to login using the admin/test page. I can login with the setup if I am not using Artifact binding so the user name / password and configuration is known to work.

If the ProtocolBinding is set as above to Artifact for the SP then attempts to login on the admin/test page for default-sp show the following error:

SimpleSAML\Error\Error: UNHANDLEDEXCEPTION
Backtrace:
2 src/SimpleSAML/Error/ExceptionHandler.php:36 (SimpleSAML\Error\ExceptionHandler::customExceptionHandler)
1 vendor/symfony/error-handler/ErrorHandler.php:538 (Symfony\Component\ErrorHandler\ErrorHandler::handleException)
0 [builtin] (N/A)
Caused by: Exception: No metadata found for remote provider with SHA1 ID: '590bac9232f900a94ff72543dec1da62ed7c078f'
Backtrace:
5 vendor/simplesamlphp/saml2/src/SAML2/HTTPArtifact.php:116 (SAML2\HTTPArtifact::receive)
4 modules/saml/src/IdP/SAML2.php:392 (SimpleSAML\Module\saml\IdP\SAML2::receiveAuthnRequest)
3 [builtin] (call_user_func_array)
2 src/SimpleSAML/HTTP/RunnableResponse.php:68 (SimpleSAML\HTTP\RunnableResponse::sendContent)
1 vendor/symfony/http-foundation/Response.php:423 (Symfony\Component\HttpFoundation\Response::send)
0 public/module.php:24 (N/A)

The SSP logs show:

Apr 10 09:42:29 simplesamlphp DEBUG [5fd0c89c64] Sending SAML 2 AuthnRequest to 'urn:x-simplesamlphp:sspsmall-idp'
Apr 10 09:42:29 simplesamlphp INFO [5fd0c89c64] SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP endpoint SSOService
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] SimpleSAML\Error\Error: UNHANDLEDEXCEPTION
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] Backtrace:
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 2 /opt/sspsmall/src/SimpleSAML/Error/ExceptionHandler.php:36 (SimpleSAML\Error\ExceptionHandler::customExceptionHandler)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 1 /opt/sspsmall/vendor/symfony/error-handler/ErrorHandler.php:538 (Symfony\Component\ErrorHandler\ErrorHandler::handleException)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 0 [builtin] (N/A)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] Caused by: Exception: No metadata found for remote provider with SHA1 ID: '590bac9232f900a94ff72543dec1da62ed7c078f'
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] Backtrace:
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 5 /opt/sspsmall/vendor/simplesamlphp/saml2/src/SAML2/HTTPArtifact.php:116 (SAML2\HTTPArtifact::receive)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 4 /opt/sspsmall/modules/saml/src/IdP/SAML2.php:392 (SimpleSAML\Module\saml\IdP\SAML2::receiveAuthnRequest)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 3 [builtin] (call_user_func_array)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 2 /opt/sspsmall/src/SimpleSAML/HTTP/RunnableResponse.php:68 (SimpleSAML\HTTP\RunnableResponse::sendContent)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 1 /opt/sspsmall/vendor/symfony/http-foundation/Response.php:423 (Symfony\Component\HttpFoundation\Response::send)
Apr 10 09:42:29 simplesamlphp ERROR [5fd0c89c64] 0 /opt/sspsmall/public/module.php:24 (N/A)

The SAML Tracer shows a single SAML entry for a GET at

https://FQDN/sspsmall/module.php/saml/idp/singleSignOnService?
SAMLart=AAQAA...&
RelayState=https%3A%2F%2FFQDN%2Fsspsmall%2Fmodule.php%2Fadmin%2Ftest%2Fdefault-sp HTTP/1.1

The SAML tab of Tracer shows

Endpoint Index: 0000
Source ID: 590b...

@monkeyiq
Copy link
Contributor Author

With this PR applied the login flow for admin/test becomes

GET https://FQDN/sspsmall/module.php/saml/idp/singleSignOnService?
SAMLRequest=jVJd...&
RelayState=https%3A%2F%2FFQDN%2Fsspsmall%2Fmodule.php%2Fadmin%2Ftest%2Fdefault-sp

The SAML page (the SAMLRequest) is as follows. Note that the ProtocolBinding is set to Artifact in the message.

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                    ID="_5d2bb..."
                    Version="2.0"
                    IssueInstant="2025-04-10T00:01:24Z"
                    Destination="https://FQDN/sspsmall/module.php/saml/idp/singleSignOnService"
                    AssertionConsumerServiceURL="https://FQDN/sspsmall/module.php/saml/sp/saml2-acs.php/default-sp"
                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
                    >
    <saml:Issuer>https://sspsmall.example.org/</saml:Issuer>
    <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
                        AllowCreate="true"
                        />
</samlp:AuthnRequest>

The next SAML Trace message is a GET sending the SAMLart back to the SP.

GET https://FQDN/sspsmall/module.php/saml/sp/saml2-acs.php/default-sp?
SAMLart=AAQAA...&
RelayState=https%3A%2F%2FFQDN%2Fsspsmall%2Fmodule.php%2Fadmin%2Ftest%2Fdefault-sp HTTP/1.1

I think it will be interesting to dig into the background Artifact resolution messages some more. The logs show some information about the background exchange.

Apr 10 10:10:34 simplesamlphp DEBUG [5fd0c89c64] ArtifactResolutionService endpoint being used is := https://FQDN/sspsmall/saml2/idp/ArtifactResolutionService.php
Apr 10 10:10:34 simplesamlphp DEBUG [5fd0c89c64] Valid ArtifactResponse received from IdP
Apr 10 10:10:34 simplesamlphp DEBUG [5fd0c89c64] Loading state: '_1e6fa...b'
Apr 10 10:10:34 simplesamlphp DEBUG [5fd0c89c64] Received SAML2 Response from 'urn:x-simplesamlphp:sspsmall-idp'.

@monkeyiq
Copy link
Contributor Author

The change in this PR does allow a login to happen. Looking at saml-bindings-2.0-os.pdf page 33 line number 1216 onwards it seems the Artifact flow here should be sending the SAMLart as in the current code and the IdP would then perform a SOAP call to the SP to ask for the actual SAML message (samlp:AuthnRequest) sent inside a samlp:ArtifactResponse.

I will dig into the code a bit more to see if there is a way I can get that flow to happen.

@monkeyiq monkeyiq marked this pull request as draft April 10, 2025 00:37
@monkeyiq
Copy link
Contributor Author

On the other hand if one is attempting to send the initial samlp:AuthnRequest by sending an Artifact from the SP to the IdP then you run into code such as the below. The code below appears to be aimed at allowing an SP to lookup metadata for an IdP to contact it for the artifact resolution.

https://github.com/simplesamlphp/saml2/blob/8419f77e10c8c91168ed4f95d33d56b7dda59096/src/SAML2/HTTPArtifact.php#L137

The code path works OK if the IdP has sent back an Artifactto the SP. In that case the SP can lookup the IdP remote information to perform the artifact resolution. There seems to be no code handling the case for if an SP wants to send the initial samlp:AuthnRequest by storing it in a local artifact store and sending just the SAMLart to the IdP expecting the IdP to resolve the artifact against the SP to work out that an AuthnRequest was wanting to be sent (by an ArtifactResolve).

@tvdijen tvdijen force-pushed the simplesamlphp-2.4 branch 2 times, most recently from e79437c to 93ca2d0 Compare April 16, 2025 20:54
@tvdijen tvdijen force-pushed the simplesamlphp-2.4 branch from 84e2e2f to 93ca2d0 Compare April 24, 2025 16:40
@monkeyiq
Copy link
Contributor Author

monkeyiq commented May 4, 2025

I will add some test suite action for these as a next stage as time permits. It seems you can use the artifact binding in more places than this PR is targeting. On the other hand the SSP code doesn't seem to have direct support for that wider range of use cases at the moment.

@tvdijen tvdijen force-pushed the simplesamlphp-2.4 branch 2 times, most recently from 0f023ea to f3f5ea3 Compare May 29, 2025 17:21
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

Successfully merging this pull request may close these issues.

1 participant

X Tutup