SAML Single Logout Service initiated by Identity Provider issue on 1.8.0-rc3

Hi,

I’m trying to integrate Xibo CMS (1.8-rc3) in our BackOffice.

Though I decided to use SAML authentication. So what I need is:

  • Single Sign On Profile
  • Single Logout Service initiated by Xibo
  • Single Logout Service initiated by our Identity Provider

The issue I’m encountering is that the SLS initiated by the Idp is not working well. Xibo SAMLAuthentication middleware create a proper response to my SAML LogoutRequest but the session is not deleted.

Thank you

After investigating, I found out that the overall logout process cause trouble with SAML.

When:

  • I use the default logout route “/logout” then the User is well logout but the SAML request is not sent to the idp.
  • I use the saml logout route (without any query parameter) “/saml/logout” then the SAML Request is sent to the idp but the User is not logout

Hmm interesting - so it appears that at a minimum the SAML middleware should register a new logout URL so that the logout link points to /saml/logout instead of /logout.

Aside from that, the route is not working as you expected when calling manually - are there any logs recorded during that process?

What do you have in your workflow config for slo? I assume true?

Hi,

Yeah I think the authentication middleware should provide both login and logout route. This would be usefull to display valid link in default theme. For example, the logout page with SAML is not “/logout” but “/saml/logout”.

What about creating a service for authentication (session management) then the authentication middleware could directly call that service to process login/logout.

Here is my SAML settings:

// https://github.com/onelogin/php-saml#settings
$samlSettings = array (
    'workflow' => array(
        // Enable/Disable Just-In-Time provisioning
        'jit' => false,
        // Attribute to identify the user
        'field_to_identify' => 'UserName',   // Alternatives: UserID, UserName or email
        // Default libraryQuota assigned to the created user by JIT
        'libraryQuota' => 0,
        // Initial User Group
        'group' => 'Users',
        // Home Page
        'homePage' => 'dashboard',
        // Enable/Disable Single Logout
        'slo' => true,
        // Attribute mapping between XIBO-CMS and the IdP
        'mapping' => array (
            'UserID' => 'id',
            'usertypeid' => '',
            'UserName' => 'username',
            'email' => 'email',
            'ref1' => '',
            'ref2' => '',
            'ref3' => '',
            'ref4' => '',
            'ref5' => ''
        )
    ),
    // If 'strict' is True, then the PHP Toolkit will reject unsigned
    // or unencrypted messages if it expects them to be signed or encrypted.
    // Also it will reject the messages if the SAML standard is not strictly
    // followed: Destination, NameId, Conditions ... are validated too
    'strict' => false,

    // Enable debug mode (to print errors).
    'debug' => true,
    'idp' => array (
        // Identifier of the IdP entity  (must be a URI)
        'entityId' => $parameters["studio_idp"]["url"] . '/security/saml/metadata',
        // SSO endpoint info of the IdP. (Authentication Request protocol)
        'singleSignOnService' => array (
            // URL Target of the IdP where the Authentication Request Message
            // will be sent.
            'url' => $parameters["studio_idp"]["url"]. '/security/saml/sso/login',
            // SAML protocol binding to be used when returning the <Response>
            // message. OneLogin Toolkit supports the HTTP-Redirect binding
            // only for this endpoint.
            'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
        ),
        // SLO endpoint info of the IdP.
        'singleLogoutService' => array (
            // URL Location of the IdP where SLO Request will be sent.
            'url' => $parameters["studio_idp"]["url"]. '/security/saml/sso/logout',
            // SAML protocol binding to be used when returning the <Response>
            // message. OneLogin Toolkit supports the HTTP-Redirect binding
            // only for this endpoint.
            'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
        ),
        // Public x509 certificate of the IdP
        'x509cert' => $parameters["studio_idp"]["x509cert"],
    ),

    // Service Provider Data that we are deploying.
    'sp' => array (
        // Identifier of the SP entity  (must be a URI)
        'entityId' => $parameters["xibo_sp"]["url"] . '/saml/metadata',
        // Specifies info about where and how the <AuthnResponse> message MUST be
        // returned to the requester, in this case our SP.
        'assertionConsumerService' => array (
            // URL Location where the <Response> from the IdP will be returned
            'url' => $parameters["xibo_sp"]["url"] . '/saml/acs',
            // SAML protocol binding to be used when returning the <Response>
            // message. OneLogin Toolkit supports this endpoint for the
            // HTTP-POST binding only.
            'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
        ),
        // Specifies info about where and how the <Logout Response> message MUST be
        // returned to the requester, in this case our SP.
        'singleLogoutService' => array (
            // URL Location where the <Response> from the IdP will be returned
            'url' => $parameters["xibo_sp"]["url"] . '/saml/sls',
            // SAML protocol binding to be used when returning the <Response>
            // message. OneLogin Toolkit supports the HTTP-Redirect binding
            // only for this endpoint.
            'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
        ),
        // Specifies the constraints on the name identifier to be used to
        // represent the requested subject.
        // Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported
        'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress',
        'x509cert' => $parameters["xibo_sp"]["x509cert"],
        'privateKey' => $parameters["xibo_sp"]["privateKey"],
    ),
    'security' => array (

        /** signatures and encryptions offered */

        // Indicates that the nameID of the <samlp:logoutRequest> sent by this SP
        // will be encrypted.
        'nameIdEncrypted' => false,

        // Indicates whether the <samlp:AuthnRequest> messages sent by this SP
        // will be signed.  [Metadata of the SP will offer this info]
        'authnRequestsSigned' => true,

        // Indicates whether the <samlp:logoutRequest> messages sent by this SP
        // will be signed.
        'logoutRequestSigned' => true,

        // Indicates whether the <samlp:logoutResponse> messages sent by this SP
        // will be signed.
        'logoutResponseSigned' => true,

        /* Sign the Metadata
         False || True (use sp certs) || array (
                                                    keyFileName => 'metadata.key',
                                                    certFileName => 'metadata.crt'
                                                )
        */
        'signMetadata' => false,


        /** signatures and encryptions required **/

        // Indicates a requirement for the <samlp:Response>, <samlp:LogoutRequest>
        // and <samlp:LogoutResponse> elements received by this SP to be signed.
        'wantMessagesSigned' => false,
        'wantAssertionsSigned' => false,
        'wantAssertionsEncrypted' => false,
        'wantNameIdEncrypted' => false,

        // Algorithm that the toolkit will use on signing process. Options:
        //    'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
        //    'http://www.w3.org/2000/09/xmldsig#dsa-sha1'
        //    'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
        //    'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'
        //    'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'
        'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',

        // Algorithm that the toolkit will use on digest process. Options:
        //    'http://www.w3.org/2000/09/xmldsig#sha1'
        //    'http://www.w3.org/2001/04/xmlenc#sha256'
        //    'http://www.w3.org/2001/04/xmldsig-more#sha384'
        //    'http://www.w3.org/2001/04/xmlenc#sha512'
        'digestAlgorithm' => 'http://www.w3.org/2001/04/xmlenc#sha256',
    )
);

The problem is that here https://github.com/dasgarner/xibo-cms/blob/develop/lib/Middleware/SAMLAuthentication.php#L283 the SLS process should delete session. This is done here https://github.com/onelogin/php-saml/blob/master/lib/Saml2/Auth.php#L243 but unfornutatly it doesn’t affect the session as I think the session is handle in database instead of file…

Whatever, it differ from github.com/dasgarner/xibo-cms/blob/develop/lib/Controller/Login.php#L151

It shouldn’t matter, because after processSLO our middleware redirects to /logout, which will delete the session. Unless of course there are some errors with the SLO process.

That will be called when the /logout route is processed.

\that is not something we will be embarking on at this late stage of our development. We will consider it for future releases though (our move to Docker means we can consider microservices, etc).

I’ve done this already - see attached issue for patch

Ok, you’re right but there is an exception when it’s Idp initiated as you can see here php-saml/lib/Saml2/Auth.php at master · SAML-Toolkits/php-saml · GitHub the user is redirected to send back the LogoutResponse so the user is never redirected to /logout route.

Great to know !

So are you suggesting that we need to provide a user function to the processSLO call here, so that we clean the session and essentially “do the logout” on our side at that point?

If so, I can see how that would work.

I’m not sure we’d ever need to redirect to /logout afterwards in that case? As the user will always be logged out by the time we get to the end of processSLO.

I’m just keen to make sure i’ve understood correctly.

Yes, I think the better way to fix that is to give to processSLO a $cbDeleteSession callback

OK, i’ve submitted an issue for that here:

Thanks

Issue deserve a heart :slight_smile:

1 Like

:smile: saw that come in - thanks!!

Sorry but this is pretty tricky for me to test - are you able to apply the patch and test in your environment?

Patch: https://github.com/dasgarner/xibo-cms/commit/dc01d76c210a078efb2c949375ea82ec83972771

Ok I could, but as I’m using docker how can I apply the patch ?

Ok I’ve tested in my environment by reproduce your changes by hand in my docker instance and it works like a charm !

1 Like

Fantastic - I will mark it as closed then and it will be included in the next release. Thank you for your assistance.

1 Like