Shibboleth SP & Okta IdP Redirect Looping

Paul Carroll pcarroll at nfmail.net
Thu Jul 30 13:49:35 UTC 2020


Hello,

I am using Okta as my IdP.  I do not have much access to the IdP and I have to put in requests to make any changes which take some time.  The customer has setup my application in Okta and sent me the information that I should need.  I am using Shibboleth SP 3.1.0.1 and Apache 2.4.  When I browse to Apache, I am redirected to the Okta login page.  I log into Okta with a valid credentials and I am then redirected back to Apache.  However, the browser goes into a continuous redirect loop that goes back and forth between the IdP and the SP.  I have read a lot of posts on here and it always boils down to cookies.  However, I am not sure how to debug this or what to look for.  I have SSL enabled on Apache and have handlerSSL set to true and cookieProps set to https.  As far as I can tell, everything being passed back and forth over HTTPS.

I have attached the following information.
1. Apache httpd-ssl.conf
2. shibboleth2.xml
3. Okta config based on what the customer sent me
4. Okta metadata
5. Okta SAML Assertion Preview
6. Snippet from Shibboleth log with debug on
7. Firefox SAML Tracer log for one loop

Apache httpd-ssl.conf
---------------------

<VirtualHost _default_:443>
 # General setup for the virtual host
 DocumentRoot "X:/Apache24/htdocs"
 ServerName server.mycompany.com:443
 ServerAdmin pcarroll at mycompany.com
 ErrorLog "X:/Apache24/logs/ssl-error.log"
 TransferLog "X:/Apache24/logs/ssl-access.log"
 ShibCompatValidUser On
 UseCanonicalName on
 UseCanonicalPhysicalPort on

 <Location />
  AuthType shibboleth
  ShibRequestSetting requireSession true
  ShibUseHeaders On
  Require valid-user
 </Location>

 <Location /Shibboleth.sso>
  SetHandler shib
  AuthType None
  Require all granted
 </Location>

 <IfModule mod_alias.c>
  <Location /shibboleth-sp>
   AuthType None
   Require all granted
  </Location>
  Alias /shibboleth-sp/main.css C:/opt/shibboleth-sp/doc/shibboleth/main.css
 </IfModule>
</VirtualHost>

shibboleth2.xml
---------------

<SPConfig xmlns="urn:mace:shibboleth:3.0:native:sp:config" xmlns:conf="urn:mace:shibboleth:3.0:native:sp:config" clockSkew="180">

 <OutOfProcess tranLogFormat="%u|%s|%IDP|%i|%ac|%t|%attr|%n|%b|%E|%S|%SS|%L|%UA|%a" />

 <StorageService type="Memory" id="mem" cleanupInterval="900"/>
 <SessionCache type="StorageService" StorageService="mem" cacheAssertions="false" cacheAllowance="900" inprocTimeout="900" cleanupInterval="900"/>
 <ReplayCache StorageService="mem"/>
 <ArtifactMap artifactTTL="180"/>

 <ApplicationDefaults entityID="https://server.mycompany.com" REMOTE_USER="eppn subject-id pairwise-id persistent-id NameID" sessionHook="/Shibboleth.sso/AttrChecker" cipherSuites="DEFAULT:!EXP:!LOW:!aNULL:!eNULL:!DES:!IDEA:!SEED:!RC4:!3DES:!kRSA:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1">
  <Sessions lifetime="28800" timeout="3600" relayState="ss:mem" redirectLimit="host" handlerURL="/Shibboleth.sso" checkAddress="false" handlerSSL="true" cookieProps="https">
   <SSO entityID="http://www.okta.com/$externalKey" forceAuthn="false" postArtifact="true" SPNameQualifier="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">SAML2 SAML1</SSO>

   <Logout>SAML2 Local</Logout>
   <LogoutInitiator type="Admin" Location="/Logout/Admin" acl="127.0.0.1 ::1" />
   <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
   <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
   <Handler type="Session" Location="/Session" showAttributeValues="true"/>
   <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
   <Handler type="AttributeChecker" Location="/AttrChecker" template="attrChecker.html" attributes="NameID" flushSession="true"/>
  </Sessions>

  <Errors supportContact="pcarroll at mycompany.com" helpLocation="/about.html" styleSheet="/shibboleth-sp/main.css"/>
  <MetadataProvider type="XML" validate="true" path="C:/opt/shibboleth-sp/etc/shibboleth/okta-metadata.xml"/>
  <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
  <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
  <CredentialResolver type="File" key="sp-signing-key.pem" certificate="sp-signing-cert.pem"/>
 </ApplicationDefaults>
 <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
 <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
</SPConfig>

Okta Configuration
------------------

Single Sign On URL: https://server.mycompany.com
Use this for Recipient URL and Destination URL: Checked
Allow this app to request other SSO URLs: Not Checked

Audience URI (SP Entity ID): https://server.mycompany.com
Default RelayState: Blank

Name ID format: Persistent
Application username: Okta username


Okta Metadata
-------------

<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.okta.com/$externalKey">
 <md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
  <md:KeyDescriptor use="signing">
   <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:X509Data>
     <ds:X509Certificate>CERTIFICATE STRING HERE</ds:X509Certificate>
    </ds:X509Data>
   </ds:KeyInfo>
  </md:KeyDescriptor>
  <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
  <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
  <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://mycompany.okta.com/app/appName/$externalKey/sso/saml"/>
  <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://mycompany.okta.com/app/appName/$externalKey/sso/saml"/>
 </md:IDPSSODescriptor>
</md:EntityDescriptor>

Okta SAML Assertion Preview
---------------------------

<?xml version="1.0" encoding="UTF-8"?>
<saml2:Assertion ID="id##########################" IssueInstant="2020-07-27T18:12:58.953Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
 <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/Issuer</saml2:Issuer>
 <saml2:Subject>
  <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">userName</saml2:NameID>
  <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
   <saml2:SubjectConfirmationData NotOnOrAfter="2020-07-27T18:17:58.955Z" Recipient="https://server.mycompany.com"/>
  </saml2:SubjectConfirmation>
 </saml2:Subject>
 <saml2:Conditions NotBefore="2020-07-27T18:07:58.955Z" NotOnOrAfter="2020-07-27T18:17:58.955Z">
  <saml2:AudienceRestriction>
   <saml2:Audience>https://server.mycompany.com</saml2:Audience>
  </saml2:AudienceRestriction>
 </saml2:Conditions>
 <saml2:AuthnStatement AuthnInstant="2020-07-27T18:03:33.646Z">
  <saml2:AuthnContext>
   <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
  </saml2:AuthnContext>
 </saml2:AuthnStatement>
</saml2:Assertion>

shib.log DEBUG
--------------

2020-07-29 12:52:17 DEBUG XMLTooling.StorageService [1] [default]: inserted record (33584a85e39f2aa9e3bfc42cc14f99eec09721f11b2961f73f69c1977e570f4c) in context (RelayState) with expiration (1596036737)
2020-07-29 12:52:17 DEBUG OpenSAML.MessageEncoder.SAML2Redirect [1] [default]: validating input
2020-07-29 12:52:17 DEBUG OpenSAML.MessageEncoder.SAML2 [1] [default]: tracking request (_4df9a7d41e503926020e72047a62c75b) against RelayState token (ss:mem:33584a85e39f2aa9e3bfc42cc14f99eec09721f11b2961f73f69c1977e570f4c)
2020-07-29 12:52:17 DEBUG OpenSAML.MessageEncoder.SAML2Redirect [1] [default]: marshalling, deflating, base64-encoding the message
2020-07-29 12:52:17 DEBUG OpenSAML.MessageEncoder.SAML2Redirect [1] [default]: marshalled message:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://server.mycompany.com/Shibboleth.sso/SAML2/POST" Destination="https://mycompany.okta.com/app/appName/$externalKey/sso/saml" ID="_4df9a7d41e503926020e72047a62c75b" IssueInstant="2020-07-29T15:22:17Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://server.mycompany.com</saml:Issuer><samlp:NameIDPolicy AllowCreate="1" SPNameQualifier="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/></samlp:AuthnRequest>
2020-07-29 12:52:17 DEBUG OpenSAML.MessageEncoder.SAML2Redirect [1] [default]: message encoded, sending redirect to client

SAML Tracer REQUEST
-------------------

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
 AssertionConsumerServiceURL="https://server.mycompany.com/Shibboleth.sso/SAML2/POST"
 Destination="https://mycompany.okta.com/app/appName/$externalKey/sso/saml"
 ID="_77b6eaac9983a769ed1e126a2391c7b1"
 IssueInstant="2020-07-29T19:40:57Z"
 ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
 Version="2.0"
>
 <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://server.mycompany.com</saml:Issuer>
 <samlp:NameIDPolicy AllowCreate="1" SPNameQualifier="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
</samlp:AuthnRequest>

SAML Tracer RESPONSE
--------------------

<saml2p:Response Destination="https://server.mycompany.com"
 ID="id320515208323019711471829902"
 InResponseTo="_77b6eaac9983a769ed1e126a2391c7b1"
 IssueInstant="2020-07-29T19:41:18.948Z"
 Version="2.0"
 xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
>
 <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.okta.com/$externalKey</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="#id320515208323019711471829902">
    <ds:Transforms>
     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
    <ds:DigestValue>DIGEST VALUE HERE</ds:DigestValue>
   </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>SIGNATURE VALUE HERE</ds:SignatureValue>
  <ds:KeyInfo>
   <ds:X509Data>
    <ds:X509Certificate>CERTIFICATE STRING HERE</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 ID="id32051520832377609602256295" IssueInstant="2020-07-29T19:41:18.948Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.okta.com/$externalKey</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="#id32051520832377609602256295">
     <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
      <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
     </ds:Transforms>
     <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
     <ds:DigestValue>DIGEST VALUE HERE</ds:DigestValue>
    </ds:Reference>
   </ds:SignedInfo>
   <ds:SignatureValue>SIGNATURE VALUE HERE</ds:SignatureValue>
   <ds:KeyInfo>
    <ds:X509Data>
     <ds:X509Certificate>CERTIFICATE STRING HERE</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:2.0:nameid-format:persistent">pcarroll at MYCOMPANY.com</saml2:NameID>
   <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
    <saml2:SubjectConfirmationData InResponseTo="_77b6eaac9983a769ed1e126a2391c7b1" NotOnOrAfter="2020-07-29T19:46:18.949Z" Recipient="https://server.mycompany.com"/>
   </saml2:SubjectConfirmation>
  </saml2:Subject>
  <saml2:Conditions NotBefore="2020-07-29T19:36:18.949Z" NotOnOrAfter="2020-07-29T19:46:18.949Z" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml2:AudienceRestriction>
    <saml2:Audience>https://server.mycompany.com</saml2:Audience>
   </saml2:AudienceRestriction>
  </saml2:Conditions>
  <saml2:AuthnStatement AuthnInstant="2020-07-29T19:41:18.087Z" SessionIndex="_77b6eaac9983a769ed1e126a2391c7b1" 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>

Please let me know if you need more information.

Thanks.


More information about the users mailing list