Bouncing back and forth between SimpleSAML SP and Okta IdP

713 views
Skip to first unread message

greg.sc...@gmail.com

unread,
Mar 29, 2017, 5:38:35 PM3/29/17
to SimpleSAMLphp
I have configured Okta as my IdP and am using SimpleSAML as my SP. The config settings, code and logged output that I believe to be relevant are shown below. The redirect to the IdP is successful. After authenticating my browser is redirected back to the my SAML test page (same_sp.php), which in turn redirects back to the IdP.

authsources.php:

'default-sp' => array(
'saml:SP',

// The entity ID of the IdP this should SP should contact.
// Can be NULL/unset, in which case the user will be shown a list of available IdPs.
),

saml_sp.php (my test file):

require_once(dirname(__FILE__).'/../../simplesaml/lib/_autoload.php');
$as = new SimpleSAML_Auth_Simple('default-sp');

$as->requireAuth();

// Never get here!

$attributes = $as->getAttributes();

Log output that is repeated over and over (I've removed the time-stamps from the log lines for brevity):

Session: 'default-sp' not valid because we are not authenticated.
Saved state: '_0409d968e5aeb0be1d04be013e26bbd7d6201594a7'
Sending SAML 2 AuthnRequest to 'http://www.okta.com/xxxxxxxxxxxxxxxxxxxx'
Sending message:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_0409d968e5aeb0be1d04be013e26bbd7d6201594a7" Version="2.0" IssueInstant="2017-03-29T20:19:14Z" Destination="https://xxxxx.okta.com/app/org_name/xxxxxxxxxxxxxxxxxxxx/sso/saml" AssertionConsumerServiceURL="http://www.my_host.com/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
  <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" AllowCreate="true"/>
</samlp:AuthnRequest>

Redirect after authenticating:



Peter Schober

unread,
Mar 30, 2017, 5:02:59 AM3/30/17
to SimpleSAMLphp
* greg.sc...@gmail.com <greg.sc...@gmail.com> [2017-03-29 23:38]:
> I have configured Okta as my IdP and am using SimpleSAML as my SP. The
> config settings, code and logged output that I believe to be relevant are
> shown below. The redirect to the IdP is successful. After authenticating my
> browser is redirected back to the my SAML test page (same_sp.php), which in
> turn redirects back to the IdP.

You didn't include what response the IDP sends back to the SP, nor
whether the SP successfully establishes a local session or what
happens before sending another request to the IDP.
-peter

greg.sc...@gmail.com

unread,
Mar 30, 2017, 3:22:53 PM3/30/17
to SimpleSAMLphp, peter....@univie.ac.at
When the IdP redirects the user's browser back to my test script (same_sp.php) my script receives four cookies (two I set, XDEBUG_SESSION and PHPSESSID) and two POST values with the keys "RelayState" and "SAMLResponse". 

The first redirect back to saml_sp.php RelayState = "http://www.ddbcorp.com/passport/saml_sp.php". On subsequent redirects it is "http://www.my_host.com/simplesaml/module.php/core/postredirect.php?RedirId=_ca4716c17e4a376e32a21d2687e8e1e77c72732e04", though the RedirId value changes each time.

SAMLResponse is the following, base64 encoded:

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://www.my_host.com/passport/saml_sp.php" ID="id19876001351288363577195108" InResponseTo="_aec320c144cf4e413ba11900c7f2f15797c034d35e" IssueInstant="2017-03-30T18:57:20.494Z" Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id19876001351288363577195108">
<ds:Transforms>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>
n0+uijHcGL25JGZmIyzoi6vrd/ivCdxBobDknMbK2A4=
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
(removed for brevity)
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
(removed for brevity)
v </ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id198760013513164641170398949" IssueInstant="2017-03-30T18:57:20.494Z" Version="2.0">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id198760013513164641170398949">
<ds:Transforms>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>
ozWxaJa84FzGXP3rkDP2vPm2SsbThOQ1mObq6G5Svkg=
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
(removed for brevity)
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
(removed for brevity)
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">
128
</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData InResponseTo="_aec320c144cf4e413ba11900c7f2f15797c034d35e" NotOnOrAfter="2017-03-30T19:02:20.494Z" Recipient="http://www.my_host.com/passport/saml_sp.php" />
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotBefore="2017-03-30T18:52:20.494Z" NotOnOrAfter="2017-03-30T19:02:20.494Z" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<saml2:AudienceRestriction>
<saml2:Audience>
passport
</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement AuthnInstant="2017-03-30T18:57:20.494Z" SessionIndex="_aec320c144cf4e413ba11900c7f2f15797c034d35e" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
</saml2:Assertion>
</saml2p:Response>"

In the SimpleSAML_Auth_Simple class the requireAuth method is called. This method first calls SimpleSAML_Session::getSessionFromRequest() which returns a session object. It then calls the session object's isValid() method with $authority = "default-sp". The session object's authData property is an empty array, but this method expects it to contain an element where the key = "default-sp". As a result it logs the "Session: default-sp not valid because we are not authenticated." DEBUG message and returns FALSE.

The session object looks like this:

$sessionobject [SimpleSAML_Session]
$session::sessions = array[1]
$session::instance = null
$session->sessionId = "b76d8dfe63c585526bd377be8bf3322d"
$session->transient = 0
$session->trackid = "275751ad4c"
$session->authority = null
$session->rememberMeExpire = null
$session->dirty = 0
$session->dataStore = array[2]
$session->dataStore['SimpleSAML_Auth_State'] = array[8]
$session->dataStore['core_postdatalink'] = array[4]
$session->associations = array[0]
$session->authToken = null
$session->authData = array[0]

Because the session object's isValid() method returned false the session object's login() method is called and the cycle starts again. The data sent from the SP to the IdP is reflected in the log output I included in my original post.

I have set the logging to its most detailed level (DEBUG) and have stepped through the code using Atom's PHP Debugging function, and still can't decipher what is going wrong. Any suggestions regarding where I should be looking are greatly appreciated.

Peter Schober

unread,
Mar 30, 2017, 4:20:53 PM3/30/17
to SimpleSAMLphp
* greg.sc...@gmail.com <greg.sc...@gmail.com> [2017-03-30 21:22]:
> When the IdP redirects the user's browser back to my test script
> (same_sp.php) my script receives four cookies (two I set, XDEBUG_SESSION
> and PHPSESSID) and two POST values with the keys "RelayState" and
> "SAMLResponse".

The SAML IDP shouldn't be be posting or redirecting back to any of
your own resources (including your "saml_sp.php" script), but to the
SAML endpoints of the SimpleSAMLphp software. Only after processing
the SAML protocol message SSP would redirect further, e.g. to the
originally requested resource (communicated as RelayState to the IDP
and recived back verbatim from the IDP).

If the IDP sends SAML responses to your own code/URL then you've given
the IDP wrong metadata about your SAML deployment.

> Recipient="http://www.my_host.com/passport/saml_sp.php" />

That's your mistake then. Instead, follow the SSP documentation on how
to connect an IDP to your SP. (TL;DR: you provide the IDP with the
metadata the SSP software generates for your deployment. If the IDP
does not support provisioning an SP from SAML 2.0 metadata then you'll
need to provide the same information contained in that standardized,
machine-readable format in other ways.)

-peter

Greg Schumacher

unread,
Mar 31, 2017, 12:55:43 PM3/31/17
to SimpleSAMLphp, peter....@univie.ac.at
Thank you, Peter, you were right. I made the change you suggested and the eternal ping-pong stopped. In the past I have only set up SAML connections by exchanging meta data, either in XML or simpleSAML format, and it has worked. Okta exports its meta data as XML but doesn't offer the importation of meta data.

My next issue is that no attributes are being returned but I will create a new post if that remains true after I spend a little more time troubleshooting.

Thanks again.

Greg

Amit Sukapure

unread,
Dec 27, 2021, 6:37:03 AM12/27/21
to SimpleSAMLphp
Hi @greg, @peter

I did read your solution but was unable to understand it though. I'm facing exact same problem and has a different SP login URL, for example - http://www.my_host.com/samlsso/ssologin.php

I have configurations in OKTA with this URL. Although, I still facing the issue.

Additionally, it was working v1.17.2 but then I upgraded it to 1.19.4, and then it is doing infinite logins.

Any help is appecriated.

Tim van Dijen

unread,
Dec 28, 2021, 6:42:48 AM12/28/21
to SimpleSAMLphp
You probably have to figure out the proper settings for the sameSite-flag. That's something that has changed between the versions you mention.

- Tim

Op maandag 27 december 2021 om 12:37:03 UTC+1 schreef amit9...@gmail.com:

Amit Sukapure

unread,
Jan 3, 2022, 1:21:23 AM1/3/22
to SimpleSAMLphp
Thanks, it looks like I had a disabled session.cookie.secure as it was not working with Firefox.
To resolve, I changed it back to true, install localhost SSL for XAMPP, and tried with chrome, it worked as expected.
Reply all
Reply to author
Forward
0 new messages