SAML Inbound Security Module - Smile CDR Documentation

SAML Inbound Security Module

The SAML Inbound Security module can be used to provide user authentication and authorization to interactive endpoints in Smile CDR, such as the Web Admin Console or FHIRWeb Console.

The SAML Specification covers many use cases and patterns. Not all of these patterns are relevant to Smile CDR however. The supported parts of the SAML specification are described here.

SAML 2.0 Authentication Request Protocol

The SAML 2.0 Authentication Request Protocol is used to authenticate and authorize users to an interactive application (i.e. not a system making an API call but rather a human user signing into an application of some sort). For example, SAML Authentication Request Protocol can be used to secure access to the Smile CDR Web Admin Console module, but it cannot be used to secure access to a FHIR Endpoint.

If you are already familiar with how SAML works, you may skip this section and skip to Enabling SAML Auth.

Step 1: Authentication Request Initial Launch This flow begins with the user initiating a SAML Authentication Request. There are two ways to launch it:

Step 2: Redirect to IDP

The module will immediately redirect the user's browser session to the IDP server using a URL similar to the following. Note that parameter values have been truncated for readability. http://some.idp/websso?SAMLRequest=fZJfT8IwFMW%2FSnPfy7oNyGwYBkUj&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=UADfIst0h6eLWdFAKdP%2FMURoc2QW%2F46U7Ok%2FXROXDousJkhMPXBeiVYSryb

The SAMLRequest parameter contains a SAML Request XML document that has been serialized, deflated, and base64 encoded. Decoding this parameter yields a document similar to the following:

<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                     AssertionConsumerServiceURL="https://example.com:9100/login/saml2/sso/SMILECDR"
                     Destination="http://some.idp/websso"
                     ForceAuthn="false"
                     ID="ARQb35c288-3888-43ee-990b-2d0418f231fa"
                     IsPassive="false"
                     IssueInstant="2020-08-03T00:46:56.121Z"
                     ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                     Version="2.0">
   <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://example.com:9100/saml2/service-provider-metadata/SMILECDR</saml2:Issuer>
</saml2p:AuthnRequest>

Copy

Step 3: Authentication with IDP At this point, the user has been redirected to the IDP server. It may ask for credentials, or it may use an existing SSO session. Assuming the IDP server wishes to grant the user access to the requested Service Provider, it will generate and sign a SAML XML document called a Response. Step 4: Redirect to Service Provider Next, the IDP will direct the user back to the Service Provider and will include a SAML Response document as a part of the redirect. This is typically performed using an HTML FORM with a POST action that is automatically submitted. The following is an example of a SAML Response document:

<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Version="2.0" ID="12345" IssueInstant="2020-08-03T00:46:56.397Z">
  <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://example.com/idp</saml2:Issuer>
  <saml2p:Status><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" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="assertion-id-1234" IssueInstant="2020-08-03T00:46:56.397Z" Version="2.0">
    <saml2:Issuer>http://example.com/idp</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/2000/09/xmldsig#rsa-sha1"/>
        <ds:Reference URI="#assertion-id-1234">
          <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#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xsd"/></ds:Transform>
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
          <ds:DigestValue>4+090Sm0RWBVi82T92jqco4rQyyaDnWYdxcWfObQuAs=</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>
        LHiJn4R6GmjuImJHbO69eLUHGSZqYHDwMmDn1tUYltAHa6Y956VK5CzN/IJT6UpZ0QkzUVRpNCs9&#xD; rwKbrNwPuuG4f9n0xdl06vJ/wsT6VS77UMDCz8OUOzKv7CIKWfWdtrRKoqiO8Q8ELkByRAXL6bOS&#xD; s8/n6cWKmLYebLfV3X5glgVilzFEpa173s+EU7RjBVJ1z96Aqqcmsc1+BOfb1v2ZFIAUFX3Jl5jy&#xD;
        LLnB/pUqQV5RNLCryyB+JY4Nv/MVKBcVI1ym5hWTp8ISg6Y7fqdF7V1VKXD29GfEMIDxHYmma4Xz&#xD; VjUCoXgAa92S5X2xwxHFULqpnVwRxROyEdMAMYw6zlaGw7oeRjD+ham/38KB2GBO456eeGsj4Gh/&#xD; RjlvE4maDBHyuW0dDZRK6wuKUoAN/FD3nFDiygzZFG0XIixKoHGq/OQTdLqUNvVW/8qZ0enEmxfk&#xD;
        Uq6MJvujytd2igyZcEpj67fp4ZCNK/BUdGAom/HSIilav+1B3Y/upzx+txyzAxQzF+0etvNZ+1MP&#xD; QVkd9T+dfsJFZ6x9INuBsji31KBZ/QCPkV0CJlWrB7xTDRfnX/wXi7xe39Ra7DSj3JRllNGGfRJ5&#xD; BdjouLHsBS/xGSuGNjCJdgFFkGiH70nbxIaEEc44wmcC9s2CQftr0TWUja0i6oKAs3eseWFgvHY=
      </ds:SignatureValue>
    </ds:Signature>
    <saml2:Subject>
      <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" NameQualifier="My Website">UserJohnSmith</saml2:NameID>
      <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml2:SubjectConfirmationData NotBefore="2020-08-03T00:46:56.397Z" NotOnOrAfter="2020-08-03T00:48:56.397Z"/></saml2:SubjectConfirmation>
    </saml2:Subject>
    <saml2:AuthnStatement AuthnInstant="2020-08-03T00:46:56.399Z" SessionIndex="abcdedf1234567" SessionNotOnOrAfter="2020-08-03T00:46:56.404Z">
      <saml2:AuthnContext>
        <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef>
      </saml2:AuthnContext>
    </saml2:AuthnStatement>
    <saml2:AttributeStatement>
      <saml2:Attribute Name="FirstName">
        <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">John</saml2:AttributeValue>
      </saml2:Attribute>
      <saml2:Attribute Name="LastName">
        <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">Smith</saml2:AttributeValue>
      </saml2:Attribute>
      <saml2:Attribute Name="http://example.com/roles">
        <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">AdminUser</saml2:AttributeValue>
      </saml2:Attribute>
    </saml2:AttributeStatement>
  </saml2:Assertion>
</saml2p:Response>

Copy

The SAML Response document contains (among other things) the following:

Enabling SAML Authentication

To enable SAML Authentication for a Smile CDR module such as the Web Admin Console, follow the following steps.

Create a Registration for Smile CDR in your IDP In your IDP system, create a new registration (your IDP may call this something else, such as an Application, or an Application Profile) for authenticating users to your system. You will need to come up with an ID (called a Registration ID by Smile CDR) that uniquely identifies the integration between Smile CDR and your IDP. By default the string SMILECDR will be used.

The IDP will likely need to know the SSO URL for the application being authenticated. This will be the following, where the host and port (and possibly also an additional context root) will correspond to the address for the Smile CDR endpoint module being authenticated. For example, if you have a Web Admin Console module on server example.com at port 9100, your base URL will be: https://example.com:9100/login/saml2/sso/REGISTRATION_ID

Create a Keystore

Next, you will need to create a Keystore file. This file should contain the certificate used to verify the signed assertions. If you are using signed Authentication Requests, it should also contain the key and certificate that will be used to perform this signature.

Create a SAML Inbound Security Module In the Web Admin Console, create a new module of type SAML Inbound Security. Enter the appropriate settings for your IDP.

Issuer ID – This should contain the ID for the IDP, and must match the value configured in that system. This is also sometimes called an Entity ID (and specifically refers to the Entity ID for the IDP/SAML Server itself). By convention this is generally a URL to the IDP server, but Smile CDR will not attempt to resolve it.

Web SSO URL – This is the URL to the IDP SSO endpoint. Smile CDR will redirect users to this URL when a login is needed.

Enable SAML in your Endpoint In the module that is being SAML-enabled:

Try It Out! There are three ways to start a login:

IDP-initiated launch – If your IDP supports it, launch Smile CDR directly from the IDP.

Entity ID Template

The Entity ID Template controls the SAML Entity ID assigned to the SAML Relying Party, which refers to the application being authenticated. For example, if you are using a SAML IDP to authenticate access to the Smile CDR Web Admin Console module, this setting controls the Entity ID that the SAML Server will know the Web Admin Console by.

This setting is important, because a well configured SAML Server should include an Audience identifier in assertions that it issues, and the Entity ID that Smile CDR uses must match the Audience declaration in the SAML Assertion.

This setting may include the following substitution variables:

{baseUrl} Refers to the base URL for the web application being authenticated. For example, if the Web Admin Console module is secured using the SAML Inbound Security module, this variable will be replaced with the base URL for the Web Admin Console module. This value will be different for each module that is secured using the same SAML Inbound Security module, which is helpful since it allows an Entity ID to be unique per authenticated module.
{registrationId} The SAML Registration ID assigned to this SAML configuration.
{baseScheme} The protocol (typically https) used in the base URL.
{baseHost} The host name used in the base URL.
{basePort} The port number used (or implied by the protocol) in the base URL.

The default value for this setting is the following:

{baseUrl}/saml2/service-provider-metadata/{registrationId}

For example, when using a default registration ID and authenticating a Web Admin Console module that is deployed to https://smilecdr.example.com:9100, the default value will be translated to the following URL (which should be configured exactly as such in the SAML Provider settings):

https://smilecdr.example.com:9100/saml2/service-provider-metadata/SMILECDR

If you prefer, you can simply hard code a value in this field with no substitution variables. By convention this value should be a URL, but it does not have to be.

Authentication Scripts

The authentication script provides a method called authenticate that is called automatically when a SAML token has been received and verified. Smile CDR will automatically validate signatures, timestamps, etc. in order to ensure that the token itself is valid for use. The script should then translate the data in the token into a session object containing the appropriate user demographics, permissions, etc.

Function: authenticate(theRequest, theOutcomeFactory)

This function will be invoked once for each token received, and should return a session or an error.

Parameters

Example

The following example script expects custom attributes named "FirstName", "LastName", and "http://example.com/roles". See the example SAML Response above to see how these attributes might look.

/*
 * This is an authentication script for the saml-inbound-security
 * module. It is required to contain a function called "authenticate".
 *
 * This function takes two parameters:
 *   - theRequest       : This object contains the incoming credentials.
 *   - theOutcomeFactory: This is a factory for the success/failure responses
 *                        to be returned by this function.
 */
function authenticate(theRequest, theOutcomeFactory) {

let samlResponse = theRequest.samlResponseDocument;

// Create a successful login response
   var success = theOutcomeFactory.newSuccess();
   success.username = theRequest.username;
   success.familyName = samlResponse.getXPathValue("/saml2p:Response/saml2:Assertion/saml2:AttributeStatement/saml2:Attribute[@Name='LastName']/saml2:AttributeValue/text()");
   success.givenName = samlResponse.getXPathValue("/saml2p:Response/saml2:Assertion/saml2:AttributeStatement/saml2:Attribute[@Name='FirstName']/saml2:AttributeValue/text()");

// Extract the custom role attribute
   let roles = samlResponse.getXPathValues("/saml2p:Response/saml2:Assertion/saml2:AttributeStatement/saml2:Attribute[@Name='http://example.com/roles']/saml2:AttributeValue/text()");

// We'll log a few attributes - In a real system you might reduce these to debug level
   Log.info("GivenName: " + success.givenName);
   Log.info("User has roles: " + roles);

// If the user has an admin role, we'll make them a superuser
   if (roles.includes('AdminUser')) {
      success.addAuthority('ROLE_SUPERUSER');
   }

// You can also reject the session based on specific criteria if needed
   if (roles.includes('BannedUser')) {
      var failure = theOutcomeFactory.newFailure();
      failure.message = 'User is banned';
      return failure;
   }

return success;

}

Copy

Authorizing SMART on FHIR Apps using SAML

See SAML to SMART Bridging for a description of how to use this module to provide authentication and authorization for SMART on FHIR apps.

Scripted Inbound Security Module

SAML Inbound Security Module

Security

Authentication Protocols Authorization and Consent Inbound Security Module Local Inbound Security Module LDAP Inbound Security Module Scripted Inbound Security Module SAML Inbound Security Module Trusted Client Mode Roles and Permissions Callback Scripts Anonymous Access Consent Service Consent Service: JavaScript API Consent Service: Java API Security Recipes Two Factor Authentication Password Hashing Algorithms JWT Signature Algorithms Troubleshooting Security

Trusted Client Mode