Healthx SAML Single Sign-On (Inbound)

Healthx supports the SAML standard for inbound SSOs. SAML is one of the most common standards for identity management at the web level. This document will not describe the SAML standard in depth. For that, we recommend you review some of the excellent documentation provided at saml.xml.org or wikipedia.

OK, How does the Healthx SAML Implementation Work?

Security Assertion Markup Language (SAML) allows secure web domains to exchange identity information with one another. This means users can log in and authenticate at one website, and that website can vouch for that user to another website.

With SAML, your web application will act as the identity provider for a user. You'll authenticate that user, then pass an encoded SAML response identifying a user to Healthx, the service provider.


Three Phases to SAML Authentication with Healthx

  1. First, your application authenticates a user.
  2. Second, your application creates a SAML2.0 assertion and posts this assertion to a supplied Healthx URL.
  3. Finally, Healthx receives this assertion, validates it, and automatically logs the user in to the Healthx application.



Security

Healthx works with highly sensitive health care data. For this reason, Healthx requires that all SAML-based HTML requests take place over secure HTTP (HTTPS).  The Healthx SAML implementation uses X.509 certificates to certify and sign requests. Healthx supports two signed-and-encrypted responses. You can either sign the entire XML string or just the SAML Assertion portion of the string. Once signed, post it to the supplied Healthx SSO URL in a field called "SAMLResponse." We recommend signing only the assertion. Healthx will verify that the SAML response came from you, by validating against the public key you've previously supplied. 

An example of of such a post in a simple HTML form is below.

Sample HTTP Post

<html>
<body onload="javascript:document.forms[0].submit()">
<noscript>
<p><strong>Note:</strong> Since your browser does not support JavaScript, you must press the Resume button once to proceed.</p>
</noscript>
<form method="post" action="http://sampleurl.healthx.com/uniqueurl">
<input type="hidden" name="SAMLResponse" value="PFJlc3BvbnL1N1cHBvcnRnNlPg%3d%3d"/>
<noscript><input type="submit" value="Resume"/></noscript>
</form>
</body>
</html>


Sample Pre-signed XML

Below is some sample XML that would be signed and posted to Healthx in the SamlResponse field above.

<Response xmlns="urn:oasis:names:tc:SAML:2.0:protocol" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="http://www.healthx.com/endpoint-url" ID="R7ee2a902-ca91-40fc-a2c4-6e2fbf7f7ea4" IssueInstant="2013-06-24T15:58:59.944Z" Version="2.0">
  <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="#R7ee2a902-ca91-40fc-a2c4-6e2fbf7f7ea4">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>PwtybRpvQ9YVa+v0OdE9BIpElDs=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>CysphYlBiRUxAq0JgxaTXLqleDfgctZTfqLHpg1x1fR9fhbGeYaLII+aYL16UxGhxHV+o1sg2J00SpGKHJMCm9mAY+FPrVZDhkgagP+Mzdxjm1MoIH5FzyK/JhWJRKJHBQbRUz/QaObAHBaBTTuRme3XN4zxJlwh4t3SSL1krRM=</SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509IssuerSerial>
          <X509IssuerName>CN=Healthx Test Certificate</X509IssuerName>
          <X509SerialNumber>5999782545553227370133761051242316812</X509SerialNumber>
        </X509IssuerSerial>
        <X509Certificate>MIICIzCCAYygAwIBAgIQBIOEHj1/rqpDRSz0L3zEDDANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhIZWFsdGh4IFRlc3QgQ2VydGlmaWNhdGUwHhcNMDgxMDMxMTQ0MTIzWhcNMzkxMjMxMjM1OTU5WjAjMSEwHwYDVQQDExhIZWFsdGh4IFRlc3QgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKY6KxFC7auRwFb2IvX1B4YsUkbYpDuhy2RspV6v4YJfAXXmTC/522OLKJVp6mHrPRjmM6OKN3E0W2byNlGTcYX82HHfbX7XIVyjtD2wptIYKu8YOE0NLY3CTrOLDxKyfCSKYLT1Gyw1Vp6k66RcBQJm2t0mWA8AysuRnSwKkOzRAgMBAAGjWDBWMFQGA1UdAQRNMEuAEGa3Qv4isCfWXIckonY7bUyhJTAjMSEwHwYDVQQDExhIZWFsdGh4IFRlc3QgQ2VydGlmaWNhdGWCEASDhB49f66qQ0Us9C98xAwwDQYJKoZIhvcNAQEEBQADgYEARiaBwwyZaSN3AY6foY2klLSQQazDEm3+hh3h09O+VGm2TBoh+LQahRyLtiNhWJBvTHJzH+Gd0TCQyQfvB7TM2xZaLLCINgOCcQCBAO8cbNitFzBI8csamaZ6SSys1pAipGNuDh8+ZIObvPohNEkpg2MRxq9E1bgZkKmcEwkKJ0w=</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>
  <Assertion ID="_beab7252-16f2-42a7-9a6a-a89d0c996fe2" IssueInstant="2013-06-24T15:58:59.944Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
    <Issuer>https://dev.healthx.com/idp</Issuer>
    <Subject>
      <NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">7be3e9cf-6367-45cd-b9a3-d56752591694</NameID>
      <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <SubjectConfirmationData NotOnOrAfter="2013-06-24T16:03:59.944Z" Recipient="http://www.healthx.com/" />
      </SubjectConfirmation>
    </Subject>
    <Conditions NotBefore="2013-06-24T15:58:59.944Z" NotOnOrAfter="2013-06-24T16:03:59.944Z">
      <AudienceRestriction>
        <Audience>https://secure.healthx.com/PublicService/SSO/AutoLogin.aspx</Audience>
      </AudienceRestriction>
    </Conditions>
    <AuthnStatement AuthnInstant="2013-06-24T15:58:59.944Z">
      <AuthnContext>
        <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
      </AuthnContext>
    </AuthnStatement>
    <AttributeStatement>
      <Attribute Name="UserId" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="UserId">
        <AttributeValue>userid</AttributeValue>
      </Attribute>
      <Attribute Name="ServiceId" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="ServiceId">
        <AttributeValue>serviceid</AttributeValue>
      </Attribute>
      <Attribute Name="SiteId" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="SiteId">
        <AttributeValue>siteid</AttributeValue>
      </Attribute>
    </AttributeStatement>
  </Assertion>
</Response>


You will sign the XML with your private key, then base64 and URL encode the XML string. You can see the signing process described in the markup in the Reference URI element:

  <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="#R85423341-38ac-48e3-8b52-85dbfc1cb383">

This URI matches the Response ID:

<Response xmlns="urn:oasis:names:tc:SAML:2.0:protocol" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="http://sampleurl.healthx.com/endpoint-url" ID="R85423341-38ac-48e3-8b52-85dbfc1cb383" IssueInstant="2008-12-18T13:32:14.155Z" Version="2.0">


You can find the Signature specification defined at http://www.w3.org/2000/09/xmldsig#. The SAML assertion follows this specification and represents the most critical portion of the SSO.

First, notice that the Assertion ID in our example begins with an underscore.

<Assertion ID="_3c81362e-6ce3-42ce-bf6a-873d58240845"

This is because the ID must be unique, but it must take the attributes of xml type NCName, which requires that the value begin with an underscore character. It is likely that w3c will publish an updated specification for an ID attribute at some point in the future, in which case the SAML specification will update in kind. See section 1.3.4 of the SAML 2.0 Specifications for more information about this ID type. [PDF]

Accepted Attributes

The series of attributes within the attribute element are the specific claims that you will use to identify the user to Healthx. Healthx currently accepts the following attributes:

Attributes for Member

    • Version (required) (must be "1")
    • RelationshipCode (required)
    • UserId (required)
    • MemberLastName
    • MemberFirstName
    • MemberDateOfBirth (yyyymmdd)
    • UserEmailAddress
    • UserPhoneNumber
If the RelationshipCode is anything other than 18 (self), the following attributes are required:
    • UserLastName
    • UserFirstName
    • UserDateOfBirth (yyyymmdd)

Attributes for Non-member users (e.g. admins)

    • RemoteUser (required)
    • Fingerprint
If Fingerprint is absent, or present but changed, the following attributes are looked at:
    • UserFirstName (required)
    • UserLastName (required)
    • UserEmailAddress
    • UserPhoneNumber
    • UserAddress1
    • UserAddress2
    • UserAddress3
    • UserAddressCity
    • UserAddressState
    • UserAddressZipCode
    • UserDateOfBirth (yyyymmdd)
    • UserGroupNumber
    • UserGender
    • AliasFirstName
    • AliasLastName

Attributes for Providers

    • remoteUser (required) (note the lower case 'r')
    • Fingerprint
If Fingerprint is absent, or present but changed, the following attributes are looked at:
    • FirstName (required)
    • LastName (required)
    • Email (required)
    • TIN (required)
    • OrgProviderID (optional, supports single value or multiple comma-separated values)

TIN Format for Providers

The TIN attribute should contain XML in the format shown in the following example. It should be wrapped in a CDATA tag so that the XML-specific characters do not need to be encoded. Any number of TINs and NPIs can be submitted in this way, and they will be stored as part of the user account. The values should be sent with every SSO request.

<![CDATA[
    <Provider>
        <TIN ID="0123456789">
            <NPI>0123</NPI>
            <NPI>4567</NPI>
        </TIN>
        <TIN ID="1234567890">
            <NPI>1234</NPI>
        </TIN>
    </Provider>
]]>

If you do not have any TIN or NPI values to send for a user, you may send an empty set with the following XML:

<![CDATA[
    <Provider/>
]]>

Attributes for any login type

    • ImitateUserId
      • If you choose to allow it, user imitation can be performed. This means that an admin user can log in using the credentials of another user and see the portal as the other user would see it. The value of this attribute should be the Healthx UserId of the admin user who will be logged as initiating the imitation session.
    • SignupKeycode
      • This optional attribute grants the user access to programs and services. The SSO configuration allows a default SignupKeycode to be specified, so that this attribute only needs to be used if some users will have different access requirements.
    • RedirectInfo
      • This parameter is used to send the user to any page other than the portal home page after they are logged in. An example of the format is shown below. The serviceid indicates the service that the user should be sent to. Any number of parameters may be specified and they will be sent along on the URL to the service.
      • See below, or the attached SAMLTemplate.xml file for proper formatting:
<saml:Attribute Name="RedirectInfo" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="RedirectInfo">
    <saml:AttributeValue>
        <ServiceId xmlns=""><REDIRECT_SERVICEID></ServiceId>
        <SupportParams Name="<PARAM1>"><PARAM1VALUE></SupportParams>
        <SupportParams Name="<PARAM2>"><PARAM2VALUE></SupportParams>
    </saml:AttributeValue>
</saml:Attribute>



Ready to begin? E-mail to get started on your SSO into Healthx.





ċ
NonEligMember_SAMLTemplate.xml
(6k)
Joel Klee,
Aug 16, 2016, 10:25 AM
ċ
Provider_SAMLTemplate.xml
(4k)
Mike Rowe,
Mar 31, 2011, 10:22 AM
ċ
SAMLTemplate.xml
(5k)
Jay German,
Sep 24, 2009, 8:26 AM
Comments