Incoming SAML 2.0 Single Sign-On

Follow

Introduction

The main purpose of establishing a Single Sign On (SSO) process with Absorb is to allow your users a single point of entry into your system while providing them access to multiple other independent systems. With this process a user logs in with a single ID to gain access to a multitude of other systems without being prompted for different usernames and passwords.

This article discusses Incoming SAML 2.0 SSO, meaning your users will login to some external application or site and then access Absorb without entering a second set of credentials. For the purposes of this article the Absorb system will act as the Service provider (SP). Your system will act as the Identity Provider (IdP). The Absorb LMS currently supports Security Assertions Markup Language (SAML) 2.0 with Identity Provider Initiated (IdP) and Service Provider Initiated (SP) SSO. 

SAML is an industry standard for achieving SSO - you may also be interested in reviewing the below SSO options:

Please note that SSO is an additional feature that involves an additional fee and technical resources on the client side to develop and/or configure the solution.

Contents:

Setup

The following variables will need to be determined and configured as part of your SSO implementation. 

Variables Description Requirement
Portal URL This is the URL where your Absorb LMS is hosted - please contact us if you do not know this. This URL usually configured as part of your initial LMS onboarding.
e.g. https://companyname.myabsorb.com OR https://some.custom.url
Mandatory
Mode Choose the principle request mode to be used, from either Service Provider Initiated or Identity Provider Initiated.  Mandatory
Key The key is the x509 public certificate of the IdP that is used for the SAML assertion signature. You must configure Absorb with your IdP’s public key so that Absorb can verify your signed SAML assertions. Mandatory
Id Property (Unique Identifier) A unique identifier field chosen in the Absorb LMS to be used as the identifying NameID through the SAML assertion. Absorb can be configured to use the following as the Id Property:
  • UserId (Absorb)
  • Username
  • Email Address
  • External Id
  • Employee Number
Mandatory
Login URL This is the URL where Absorb redirects users if they navigate directly to the Portal URL without an active session. If the Mode is set to Identify Provider Initiated, this redirect is only triggered when the Automatically Redirect feature is turned on. Optional
Logout URL This is the URL where Absorb redirects users when they log out of the Absorb system. Optional
Automatically Redirect

When turned on, redirects all users who navigate directly to the Portal URL to the Login URL. If not turned on, users will land on the portal's landing page.

Note: For the SP Initiated Mode this setting is always enabled.

Optional
RelayState This is an optional parameter that is passed to Absorb for deep linking purposes. Please see the deep linking section for more details. Optional
Assigned Routes This field allows you to search for and select any existing routes to assign. Optional

 

With the exception of Portal URL and RelayState, all of the above variables can be configured by logging into the Absorb admin portal as a System Admin and navigating to Portal Settings. From Portal Settings, there is a button in the right-side context menu labelled Manage SSO Settings. If you can't see this button, please contact your Absorb Client Success Manager to discuss enabling the feature.

Capture2.PNG

Once you have clicked the button, you will be brought to the Manage Single Sign-On Settings page. Any existing configurations will appear here, as well as the option to Add a new one. 

Capture.PNG

 

Each route (Portal URL, e.g. company.myabsorb.com) can have its own set of SSO configuration. Please see this article for more information on route-based SSO. The remainder of this article assumes we're talking about a single SSO configuration.

 

Hybrid Setup

Your Absorb portal can be setup to use a hybrid setup where some users will login using SSO and others can login directly into your Absorb portal. There are two options for achieving this:

  • In the 'Manage Single Sign-On Settings' page (see above) you can set "Automatically Redirect" to OFF in order to allow both SSO and non-SSO users to login using the associated route(s). This only works in IdP Initiated mode, since SP initiated will always forcefully use SSO.
  • Since each route can have its own or no SSO configuration, you could have one route setup to use SSO and another one with no SSO settings. Your users would then be given different URL's depending on whether they are a SSO or non-SSO user.


How it Works

IdP Initiated

The below process assumes the Automatically Redirect option has been turned on.

Figure 1.1

  1. User attempts to navigate their browser to the Portal URL.
  2. Absorb checks to see if the Automatically Redirect option is turned on. If it is, Absorb checks what the IdP Login URL is. 
  3. Absorb redirects the user to the Login URL
  4. The IdP identifies the user (User usually types in their credentials here if they haven’t already).
  5. The IdP does a POST of a signed SAML Response with a SAML Assertion. 

    The SAML Assertion needs to have the “NameID” in the “Subject” to be mapped accordingly to the configured Id Property in Absorb. POST the SAML Response to https://Portal URL/Account/api/rest/v2/authentication/saml or https://Portal URL/Account/SAML (NLE vs. non-NLE portals, see Metadata section)

    If the IdP wishes to deep link the user to a specific resource in the Absorbs user interface the IdP can also pass a RelayState parameter along with the SAML Response. Please read the Deep Linking and RelayState section regarding relay states for more information.

  6. Absorb uses the IdP metadata (mainly the x509 public certificate/Key in the Absorb configuration) to verify the signed message from the IdP. Use your private x509 certificate to sign either (or both): 
              • The entire SAML Response

              • The SAML Assertion
  7. If authentication is Successful the user is logged into the Absorb system.
  8. Absorb checks to see if a RelayState parameter is passed along with the SAML Response. If one has been provided, Absorb will parse the RelayState value and redirect the user to the corresponding resource. Please see the Deep Linking and RelayState section for more details.


SP Initiated

Refer to Figure 1.1

  1. User attempts to navigate their browser to the Portal URL, which may include a valid Absorb deep link. E.g., https%3A%2F%2Fcompany.myabsorb.com%3FcourseId%3D8a70a2d4-21ab-4eda-9d36-50aada8ff7ae (which is the encoded version of: https://company.myabsorb.com?courseId=8a70a2d4-21ab-4eda-9d36-50aada8ff7ae)
  2. Absorb checks to see if the SP Initiated Mode is selected. If it is, Absorb checks what the IdP Login URL is.
  3. Absorb redirects the user to the Login URL with a SAML authentication request, which includes these parameters:
              • SAMLRequest – A URL-encoded, Base64-encoded, compressed (gzip) SAML message
              • SigAlg – The algorithm used to sign the SAML message
              • Signature – The digital signature used to sign the SAML message
              • RelayState – The Absorb resource requested by the client

  4. The IdP identifies the user (User usually types in their credentials here if they haven’t already).
  5. The IdP does a POST of a signed SAML Response with a SAML Assertion. 

    The SAML Assertion needs to have the “NameID” in the “Subject” to be mapped accordingly to the configured Id Property in Absorb.

    POST the SAML Response to https://Portal URL/Account/api/rest/v2/authentication/saml or https://Portal URL/Account/SAML (NLE vs. non-NLE portals, see Metadata section)

    If a deep link has been specified (refer to step #1) then a RelayState parameter will need to be returned to Absorb in the post request, which Absorb will use to redirect the user to the corresponding resource. Please read the Deep Linking and RelayState section regarding relay states for more information.

  6. Absorb uses the IdP metadata (mainly the x509 public certificate/Key in the Absorb configuration) to verify the signed message from the IdP. Use your public x509 certificate to sign either (or both):
              • The entire SAML Response
              • The SAML Assertion

  7. If authentication is Successful the user is logged into the Absorb system.

  8. Absorb checks to see if a RelayState parameter is passed along with the SAML Response. If one has been provided, Absorb will parse the RelayState value and redirect the user to the corresponding resource. Please see the Deep Linking and RelayState section for more details.
 

Metadata

Metadata is used to ensure a secure transaction between an identity provider and a service provider. 

Absorb’s SP Metadata

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor entityID="https://company.myabsorb.com" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
	<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="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>
MIID6zCCAtOgAwIBAgIJAPWWr9yo9lmBMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYDVQQGEwJDQTEQMA4GA1UECAwHQWxiZXJ0YTEQMA4GA1UEBwwHQ2FsZ2FyeTEdMBsGA1UECgwUQWJzb3JiIFNvZnR3YXJlIEluYy4xEzARBgNVBAsMCkFic29yYiBMTVMxJDAiBgNVBAMMG0Fic29yYiBMTVMgU0FNTCBDZXJ0aWZpY2F0ZTAeFw0xNzA3MjAxNzE3MDFaFw0yMDA3MTkxNzE3MDFaMIGLMQswCQYDVQQGEwJDQTEQMA4GA1UECAwHQWxiZXJ0YTEQMA4GA1UEBwwHQ2FsZ2FyeTEdMBsGA1UECgwUQWJzb3JiIFNvZnR3YXJlIEluYy4xEzARBgNVBAsMCkFic29yYiBMTVMxJDAiBgNVBAMMG0Fic29yYiBMTVMgU0FNTCBDZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM/5udlYOcVjCu2gPpG39a1m0hQGVPUGZ/GQIlofGJHXjACvu/hjrqQU5z3H1Zl/QQ7zQu6MuM2XQEZr+Hp8mpxOEn079xJ0InTknebizm9hKcbYfWqpqEoDulGJavSPNdyjGxdLrFkrJYq3lUpne0SjQwy4UIkrIfPbuDDlUesWBDHNzSwhm15TquBblN/o0syn1M4NyF32o1PfNeaC6i9GLqiZRnt2ULyYTk7W5x6MHV94b7mcEM3rNEO9x2WPZ09EK8KgIVMDoiZOq3l3p0glJ8uK0ZYrWRH3hXoM1LLNQovYlndOQNmva/UDMvqH9EF6M54+J//1s/GUuJThruECAwEAAaNQME4wHQYDVR0OBBYEFNdyoG8noim9iX2IYEWMw3E75F5gMB8GA1UdIwQYMBaAFNdyoG8noim9iX2IYEWMw3E75F5gMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADanrQs/8IiM7gI/9bxNO17MxjUEHAtVcAjOQ+a0tF9F3F5+cXNn6WmNo865ThOIDH9aJhR9Y7DaElcOAK1Zc90Ary2L52EmNPPuCYzRU8wheY5dwG1ZWaqg7XtytNmKyb3/dDON4IRWIHpJCIfe7F8X4usYN9U3M03eHb7v5n1rgTre2Wp++hq1NxpXFv48fc9+/nwYg+DofvW+73xyjRqBVmtQygZ9LfRgJ92dygrhLUa1RSfmtZFRSK1IdbSFBBVWu78cwoSR/VjQ3dIPec6siY4zDCpl7x2Tz9BuLD0q338SoIr9E2okvjDUAg4qFXSKt9jJ8t+cV2ylfp9CeG0=
					</ds:X509Certificate>
				</ds:X509Data>
			</ds:KeyInfo>
		</md:KeyDescriptor>
		<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="ACS URL" index="0" isDefault="true"/>
	</md:SPSSODescriptor>
</md:EntityDescriptor>

Important: You will need to replace the "ACS URL" value near the end with one of the following URL's, depending on which version of our learner interface you are using:

  • Absorb 5: https://company.myabsorb.com/account/saml
  • Absorb 5 - New Learner Experience: https://company.myabsorb.com/api/rest/v2/authentication/saml

(Please ensure you replace "company.myabsorb.com" with your Portal URL.)

Example with the ACS URL replaced:

	...
		<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://company.myabsorb.com/api/rest/v2/authentication/saml" index="0" isDefault="true"/>
	...

You can also add the Absorb metadata to your list of trusted Service providers if required.

IdP Metadata

Your IdP Metadata can be used to obtain your public X509 certificate. The X509 certificate should be added to the Key field under Portal Settings - see the Setup section for more details.

 

Deep Linking and RelayState

Deep linking in terms of the Absorb LMS is the ability to redirect a user to a particular user content page on the Absorb LMS. This is usually done through a hyperlink that the user would click on. 

Absorb supports deep linking through SAML via using one of SAML’s protocols implementation parameters, the RelayState. Normally, the relay state identifies the relying party trust. But Absorb uses it as an optional parameter to support deep linking.

Please note below deep links works only on UI3 . If the client is on NLE , they should use this documentation New Learner Experience Deeplink Support.

Absorb supports deep linking into the following user page content when using SAML SSO:

  1. Course
  2. Lesson
  3. Curriculum
  4. Global Resource
  5. Search page
  6. Language selection

IdP vs. SP Initiated

Deep linking works a bit differently between IdP and SP initiated SSO. For SP initiated the deep link can point directly to your Absorb portal URL, and we'll take care of passing the deep link back to the IdP in the RelayState parameter which can then be returned to us in the final SAML Response (see How it Works section for more detailed flow). For IdP initiated however the deep link must be built into the IdP's URL, picked up by the IdP, then passed to Absorb in the RelayState parameter in the final SAML Response. The important point here is that if a user lands directly on Absorb in an IdP initiated setup, the deep link is not passed back to the IdP and ultimately the user will end up on the default Absorb dashboard.

The following examples illustrate how to structure the RelayState parameter values for IdP initiated. Note the parameters must be url encoded and the full deep link URLs will need to be formulated by the IdP (client). The following examples also illustrate how to formulate deep links for SP initiated - these can essentially be used as-is, assuming the IdP is setup to receive/send the RelayState parameter appropriately.

Courses: (Online Course)

IdP Initiated: RelayState=https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FCourseId%3D91db68a0-581f-467c-84fa-e67430d1c661

SP Initiated: Deep link=https%3A%2F%2Fcompany.myabsorb.com%3FCourseId%3D91db68a0-581f-467c-84fa-e67430d1c661

Where: CourseId = Id field of an Absorb online course.

This deeplink would redirect to "Launch Course" page on Absorb if the user is enrolled in the course . If not enrolled and course has "Allow Self Enrollment" toggle on, it would open the Catalog page where user can enroll into the course if the user satisfies the self enrollment rules . If not enrolled and course has "Allow Self Enrollment" toggle off, it would open the Search page with message "No results were found" .

Courses: (Instructor Led Course)

IdP Initiated: RelayState=https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FIlcId%3D91db68a0-581f-467c-84fa-e67430d1c661

SP Initiated: Deep link=https%3A%2F%2Fcompany.myabsorb.com%3FIlcId%3D91db68a0-581f-467c-84fa-e67430d1c661

Where: IlcId = Id field of an Absorb instructor led course.

This deeplink would redirect to "Launch Course" page on Absorb if the user is enrolled in the course . If not enrolled and course has "Allow Self Enrollment" toggle on, it would open the Catalog page where user can enroll into the course if the user satisfies the self enrollment rules . If not enrolled and course has "Allow Self Enrollment" toggle off, it would open the Search page with message "No results were found" .

Lessons:

IdP Initiated: RelayState=https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FCourseId%3D91db68a0-581f-467c-84fa-e67430d1c661%26LessonId%3D4ed77b4f-3cfa-4baf-8b9f-bc92a6713658

SP Initiated: Deep link=https%3A%2F%2Fcompany.myabsorb.com%3FCourseId%3D91db68a0-581f-467c-84fa-e67430d1c661%26LessonId%3D4ed77b4f-3cfa-4baf-8b9f-bc92a6713658

Where: CourseId = Id field of an Absorb course & LessonId = Id field of an Absorb lesson.

This deeplink would open the lesson on Absorb if the user is enrolled in the course . If not enrolled and course has "Allow Self Enrollment" toggle on, it would open the Catalog page where user can enroll into the course if the user satisfies the self enrollment rules . If not enrolled and course has "Allow Self Enrollment" toggle off, it would open the Search page with message "No results were found" .

Curriculum:

IdP Initiated: RelayState=https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FCurriculumId%3Df0111f9d-5a81-4580-ad2f-69dc69496097

SP Initiated: Deep link=https%3A%2F%2Fcompany.myabsorb.com%3FCurriculumId%3Df0111f9d-5a81-4580-ad2f-69dc69496097

Where: CurriculumId = Id field of an Absorb curriculum.

This deeplink would redirect to Curricula page on Absorb and show the courses under the curricula if the user is enrolled in the curricula. If not enrolled and curricula has "Allow Self Enrollment" toggle on, it would open the Catalog page where user can enroll into the curricula if the user satisfies the self enrollment rules . If not enrolled and curricula has "Allow Self Enrollment" toggle off, it would open the Search page with message "No results were found" .

Resources:

IdP Initiated: RelayState=https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FResourceId%3D99faacc2-97d9-4989-a46c-3a989b8f71ac 

SP Initiated: Deep link=https%3A%2F%2Fcompany.myabsorb.com%3FResourceId%3D99faacc2-97d9-4989-a46c-3a989b8f71ac

Where: ResourceId = Id field of an Absorb resource.

This deeplink would open the resource on Absorb side if the user satisfies the Resource availability rules . If not , it would display message saying "No resources found".

Search:

IdP Initiated: RelayState=https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FSearch%3Dinstructor

SP Initiated: Deep link=https%3A%2F%2Fcompany.myabsorb.com%3FSearch%3Dinstructor

Where: Search = the term to search for in all searchable areas of the Absorb user interface. In this example we’re searching for the term “instructor”.

This deeplink would list all the items that match the search criteria.

Language:

IdP Initiated: RelayState=https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FLanguage%3Dfr

SP Initiated: Deep link=https%3A%2F%2Fcompany.myabsorb.com%3FLanguage%3Dfr

Where: Language = the ISO letter code representing the language. Absorb supports the following language codes:

Arabic=ar
Chinese (Simplified)=zh
Chinese (Traditional)=zht
Czech=cs
Danish=da
Dutch=nl
English=en
Finnish=fi
French=fr
German=de
Greek=el
Hebrew=he
Italian=it
Japanese=ja
Korean=ko
Mongolian=mn
Nederland=nl
Norwegian=no
Polish=pl
Portuguese=pt
Russian=ru
Spanish=es
Swedish=sv
Thai=th
Turkish=tr
Vietnamese=vi 

Please ensure you replace "company.myabsorb.com" with your Portal URL for all examples above.

Examples

SAML Response:

The following HTML code can be used to POST a form to Absorb's SAML SP endpoint. The below example includes the SamlResponse and RelayState parameters for Absorb deep linking:

<html>
<body>
	<form action="https://company.myabsorb.com/account/saml" method="POST" id="samlform">
	  SamlResponse <br><textarea name="samlresponse" id="samlresponse" rows="25" cols="50">...Base64 Encoded SAMLResponse and Assertion...</textarea><br><br>
	  RelayState <br><input type="text" name="relaystate" id="relaystate" value="...DeepLink URL..." size="100"><br>
	  <br>
	  <input type="submit" value="Submit">
	</form>
</body>
</html>

Where SamlResponse = base64 encoded SAML Response + SAML Assertion as shown here: 

Before base64 encoding: 

Please note the x509 certificate used in the example below would be replaced with one from the IdP.

<samlp:Response
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="identifier_2"
    InResponseTo="identifier_1"
    Version="2.0"
    IssueInstant="2004-12-05T09:22:05"
    Destination="https://company.myabsorb.com/account/saml">
    <saml:Issuer>https://IdP.example.org/SAML2</saml:Issuer>
    <samlp:Status>
      <samlp:StatusCode
        Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion Version="2.0" ID="_aca78291-11a2-40f2-ba16-4cfbd93865db" IssueInstant="2015-08-11T21:14:33.053Z"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml:Issuer>https://IdP.example.org/SAML2</saml:Issuer>
    <Signature
        xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
            <Reference URI="#_aca78291-11a2-40f2-ba16-4cfbd93865db">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                        <InclusiveNamespaces PrefixList="#default saml ds xs xsi"
                            xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transform>
                    </Transforms>
                    <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                    <DigestValue>T+64Rwm7xlNr2mTli9rU/Jmyd5o=</DigestValue>
                </Reference>
            </SignedInfo>
            <SignatureValue>WDjZhBehjVKAGLwe1nYMiQtCMspwZaDxnknn+eMk62kD08R8S4bt2nm4kTCaJ6hKxaQ/P7S5W8Kq0JIQV0pRqR+Y9m98CHtT97No6LQFbgBjlMXpEWyZbJ8zBpy5dJbUHOC3ZaFlnBrfLBxW0DR8l0mb6+uLs0VuqQm+5T606Dw=</SignatureValue>
            <KeyInfo>
                <X509Data>
                    <X509Certificate>MIIBnjCCAQcCBEbTmdAwDQYJKoZIhvcNAQEEBQAwFjEUMBIGA1UEAxMLd3d3LmlkcC5jb20wHhcNMDcwODI4MDM0MzEyWhcNMTcwODI1MDM0MzEyWjAWMRQwEgYDVQQDEwt3d3cuaWRwLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo31q3mJZayXfZkLDuLcnanc/KG+RDFW+OlYDP+RubvWnt8X5jtiUTcp8IQ46TNEUFskmsonUb5AnG+zOCcawb2dJr8kBtCNhfi/TufZGBQNjuAxNMi34yIgRdGinaznHgclrAIIZTyKerQqYjPL1xRDsFGpzqGGi/2opzN8nV5kCAwEAATANBgkqhkiG9w0BAQQFAAOBgQBmNwFN+98aybuQKFJFr69s9BvBVYtk+Hsx3gx0g4e5sLTlkcSU03XZ8AOet0my4RvUspaDRzDrv+gEgg7gDP/rsVCSs3dkuYuUvuWbiiTq/Hj4EKuKZa8nIerZ3Oz4Xa1/bK88eT7RVsv5bMOxgJbSEvTidTvOpV0G13duIqyrCw==</X509Certificate>
                </X509Data>
            </KeyInfo>
        </Signature>
        <saml:Subject>
            <saml:NameID>absorb.test</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml:SubjectConfirmationData Recipient="https://company.myabsorb.com/account/saml" />
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions NotBefore="2015-08-11T15:14:33.053Z" NotOnOrAfter="2015-08-11T15:19:33.053Z">
        </saml:Conditions>
        <saml:AuthnStatement AuthnInstant="2015-08-11T21:14:33.053Z">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
    </saml:Assertion>
  </samlp:Response>

 

After base64 encoding:
PHNhbWxwOlJlc3BvbnNlDQogICAgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCINCiAgICB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIg0KICAgIElEPSJpZGVudGlmaWVyXzIiDQogICAgSW5SZXNwb25zZVRvPSJpZGVudGlmaWVyXzEiDQogICAgVmVyc2lvbj0iMi4wIg0KICAgIElzc3VlSW5zdGFudD0iMjAwNC0xMi0wNVQwOToyMjowNSINCiAgICBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9jb21wYW55Lm15YWJzb3JiLmNvbS9hY2NvdW50L3NhbWwiPg0KICAgIDxzYW1sOklzc3Vlcj5odHRwczovL2lkcC5leGFtcGxlLm9yZy9TQU1MMjwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOlN0YXR1cz4NCiAgICAgIDxzYW1scDpTdGF0dXNDb2RlDQogICAgICAgIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz4NCiAgICA8L3NhbWxwOlN0YXR1cz4NCiAgICA8c2FtbDpBc3NlcnRpb24gVmVyc2lvbj0iMi4wIiBJRD0iX2FjYTc4MjkxLTExYTItNDBmMi1iYTE2LTRjZmJkOTM4NjVkYiIgSXNzdWVJbnN0YW50PSIyMDE1LTA4LTExVDIxOjE0OjMzLjA1M1oiDQogICAgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+DQogICAgPHNhbWw6SXNzdWVyPmh0dHBzOi8vaWRwLmV4YW1wbGUub3JnL1NBTUwyPC9zYW1sOklzc3Vlcj4NCiAgICA8U2lnbmF0dXJlDQogICAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgICAgICAgPFNpZ25lZEluZm8+DQogICAgICAgICAgICA8Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIgLz4NCiAgICAgICAgICAgIDxTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiIC8+DQogICAgICAgICAgICA8UmVmZXJlbmNlIFVSST0iI19hY2E3ODI5MS0xMWEyLTQwZjItYmExNi00Y2ZiZDkzODY1ZGIiPg0KICAgICAgICAgICAgICAgIDxUcmFuc2Zvcm1zPg0KICAgICAgICAgICAgICAgICAgICA8VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiIC8+DQogICAgICAgICAgICAgICAgICAgIDxUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPEluY2x1c2l2ZU5hbWVzcGFjZXMgUHJlZml4TGlzdD0iI2RlZmF1bHQgc2FtbCBkcyB4cyB4c2kiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIgLz4NCiAgICAgICAgICAgICAgICAgICAgICAgIDwvVHJhbnNmb3JtPg0KICAgICAgICAgICAgICAgICAgICA8L1RyYW5zZm9ybXM+DQogICAgICAgICAgICAgICAgICAgIDxEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIgLz4NCiAgICAgICAgICAgICAgICAgICAgPERpZ2VzdFZhbHVlPlQrNjRSd203eGxOcjJtVGxpOXJVL0pteWQ1bz08L0RpZ2VzdFZhbHVlPg0KICAgICAgICAgICAgICAgIDwvUmVmZXJlbmNlPg0KICAgICAgICAgICAgPC9TaWduZWRJbmZvPg0KICAgICAgICAgICAgPFNpZ25hdHVyZVZhbHVlPldEalpoQmVoalZLQUdMd2UxbllNaVF0Q01zcHdaYUR4bmtubitlTWs2MmtEMDhSOFM0YnQybm00a1RDYUo2aEt4YVEvUDdTNVc4S3EwSklRVjBwUnFSK1k5bTk4Q0h0VDk3Tm82TFFGYmdCamxNWHBFV3laYko4ekJweTVkSmJVSE9DM1phRmxuQnJmTEJ4VzBEUjhsMG1iNit1THMwVnVxUW0rNVQ2MDZEdz08L1NpZ25hdHVyZVZhbHVlPg0KICAgICAgICAgICAgPEtleUluZm8+DQogICAgICAgICAgICAgICAgPFg1MDlEYXRhPg0KICAgICAgICAgICAgICAgICAgICA8WDUwOUNlcnRpZmljYXRlPk1JSUJuakNDQVFjQ0JFYlRtZEF3RFFZSktvWklodmNOQVFFRUJRQXdGakVVTUJJR0ExVUVBeE1MZDNkM0xtbGtjQzVqYjIwd0hoY05NRGN3T0RJNE1ETTBNekV5V2hjTk1UY3dPREkxTURNME16RXlXakFXTVJRd0VnWURWUVFERXd0M2QzY3VhV1J3TG1OdmJUQ0JuekFOQmdrcWhraUc5dzBCQVFFRkFBT0JqUUF3Z1lrQ2dZRUFvMzFxM21KWmF5WGZaa0xEdUxjbmFuYy9LRytSREZXK09sWURQK1J1YnZXbnQ4WDVqdGlVVGNwOElRNDZUTkVVRnNrbXNvblViNUFuRyt6T0NjYXdiMmRKcjhrQnRDTmhmaS9UdWZaR0JRTmp1QXhOTWkzNHlJZ1JkR2luYXpuSGdjbHJBSUlaVHlLZXJRcVlqUEwxeFJEc0ZHcHpxR0dpLzJvcHpOOG5WNWtDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUVFGQUFPQmdRQm1Od0ZOKzk4YXlidVFLRkpGcjY5czlCdkJWWXRrK0hzeDNneDBnNGU1c0xUbGtjU1UwM1haOEFPZXQwbXk0UnZVc3BhRFJ6RHJ2K2dFZ2c3Z0RQL3JzVkNTczNka3VZdVV2dVdiaWlUcS9IajRFS3VLWmE4bkllclozT3o0WGExL2JLODhlVDdSVnN2NWJNT3hnSmJTRXZUaWRUdk9wVjBHMTNkdUlxeXJDdz09PC9YNTA5Q2VydGlmaWNhdGU+DQogICAgICAgICAgICAgICAgPC9YNTA5RGF0YT4NCiAgICAgICAgICAgIDwvS2V5SW5mbz4NCiAgICAgICAgPC9TaWduYXR1cmU+DQogICAgICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICAgICAgICA8c2FtbDpOYW1lSUQ+YWJzb3JiLnRlc3Q8L3NhbWw6TmFtZUlEPg0KICAgICAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPg0KICAgICAgICAgICAgICAgIDxzYW1sOlN1YmplY3RDb25maXJtYXRpb25EYXRhIFJlY2lwaWVudD0iaHR0cHM6Ly9jb21wYW55Lm15YWJzb3JiLmNvbS9hY2NvdW50L3NhbWwiIC8+DQogICAgICAgICAgICA8L3NhbWw6U3ViamVjdENvbmZpcm1hdGlvbj4NCiAgICAgICAgPC9zYW1sOlN1YmplY3Q+DQogICAgICAgIDxzYW1sOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDE1LTA4LTExVDE1OjE0OjMzLjA1M1oiIE5vdE9uT3JBZnRlcj0iMjAxNS0wOC0xMVQxNToxOTozMy4wNTNaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgICAgICAgICAgICAgPHNhbWw6QXVkaWVuY2U+RW5oYW5jZVU6X2NpZD0xMjIwNTA8L3NhbWw6QXVkaWVuY2U+DQogICAgICAgICAgICA8L3NhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4NCiAgICAgICAgPC9zYW1sOkNvbmRpdGlvbnM+DQogICAgICAgIDxzYW1sOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAxNS0wOC0xMVQyMToxNDozMy4wNTNaIj4NCiAgICAgICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dD4NCiAgICAgICAgICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3NlczpQYXNzd29yZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgICAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDwvc2FtbDpBdXRoblN0YXRlbWVudD4NCiAgICA8L3NhbWw6QXNzZXJ0aW9uPg0KICA8L3NhbWxwOlJlc3BvbnNlPg==

And the RelayState = URL deep link as shown here: 

https%3A%2F%2Fcompany.myabsorb.com%2Faccount%2Fsaml%3FCourseId%3D91db68a0-581f-467c-84fa-e67430d1c661

In this example we are deep linking into a particular course. Please refer to the Deep Linking and RelayState section for more details.

Please also keep in mind the HTML form shown in the example above implicitly URL encodes all data sent in the POST. So you may need to URL encode your messages if the framework you are using doesn’t already do this implicitly.

SAML AuthnRequest:

Here is an example SAML Request that would be sent as part of SP initiated mode:

Before base64 encoding:

<samlp:AuthnRequest ID="identifier_1"
                    Version="2.0"
                    IssueInstant="2017-08-16T15:32:26.225Z"
                    Destination="https://company.myabsorb.com/"
                    ForceAuthn="false"
                    IsPassive="false"
                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                    AssertionConsumerServiceURL="https://company.myabsorb.com/account/saml"
                    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    >
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://company.myabsorb.com</saml:Issuer>
</samlp:AuthnRequest>

After base64 encoding:

PHNhbWxwOkF1dGhuUmVxdWVzdCBJRD0iaWRlbnRpZmllcl8xIg0KICAgICAgICAgICAgICAgICAgICBWZXJzaW9uPSIyLjAiDQogICAgICAgICAgICAgICAgICAgIElzc3VlSW5zdGFudD0iMjAxNy0wOC0xNlQxNTozMjoyNi4yMjVaIg0KICAgICAgICAgICAgICAgICAgICBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9jb21wYW55Lm15YWJzb3JiLmNvbS8iDQogICAgICAgICAgICAgICAgICAgIEZvcmNlQXV0aG49ImZhbHNlIg0KICAgICAgICAgICAgICAgICAgICBJc1Bhc3NpdmU9ImZhbHNlIg0KICAgICAgICAgICAgICAgICAgICBQcm90b2NvbEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiDQogICAgICAgICAgICAgICAgICAgIEFzc2VydGlvbkNvbnN1bWVyU2VydmljZVVSTD0iaHR0cHM6Ly9jb21wYW55Lm15YWJzb3JiLmNvbS9hY2NvdW50L3NhbWwiDQogICAgICAgICAgICAgICAgICAgIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiDQogICAgICAgICAgICAgICAgICAgID4NCiAgICA8c2FtbDpJc3N1ZXIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cHM6Ly9jb21wYW55Lm15YWJzb3JiLmNvbTwvc2FtbDpJc3N1ZXI+DQogICAgPHNhbWxwOk5hbWVJRFBvbGljeSBTUE5hbWVRdWFsaWZpZXI9IlVzZXJuYW1lIg0KICAgICAgICAgICAgICAgICAgICAgICAgQWxsb3dDcmVhdGU9InRydWUiDQogICAgICAgICAgICAgICAgICAgICAgICAvPg0KPC9zYW1scDpBdXRoblJlcXVlc3Q+

Troubleshooting:

  • In the SAML Response POST to https://Portal URL/Account/SAML having upper case /Account/SAML can potentially cause issues. Try using lower case e.g. https://Portal URL/account/saml.
  • The SAML Response POST to https://Portal URL/Account/api/rest/v2/authentication/saml or https://Portal URL/Account/SAML needs to be signed with the same X509 key that was setup in the Absorb portal SSO settings.
  • Check that the certificate being used to sign the SAML Response hasn't expired.
  • Ensure spaces are removed from the key before copying it to your Absorb portal's SSO settings.

 

Example code (with C#):

http://www.codeproject.com/Articles/56640/Performing-a-SAML-Post-with-C

Jump back to top.

Published on
Have more questions? Submit a request

0 Comments

Article is closed for comments.