Configure SAML Authentication

Before you configure SAML, please assure you adhere to Security Advisory 2019-01 and follow the Chrome SameSite Cookie Changes recommendation.

SAML stands for Security Assertion Markup Language. It is a current standard for authenticating users in a distributed system.

Stages acts as a SAML Service Provider (SP) and interacts with a SAML IdP (Identity provider) to authenticate users.

Restrictions

Stages currently supports single sign on (SSO) only with one SAML server.

Generate a signing key

If you already have a SSL server certificate for Stages, you can use that certificate to sign the SAML requests. If you use encrypted SAML assertions - a separate certificate is required. If you do not have a certificate or you want to use a separate certificate, use the follwing command:

keytool -genkeypair -alias "samlkeyalias" -keyalg RSA -keysize 2048 -validity 1095 -keystore "conf/saml-keystore.jks"

Enter your Stages Domain Name when asked for the First and Last Name. The rest of the parameters can be set arbitrarily.

You can choose an arbitrary key name (e.g. samlkeyalias) and location for the keystore (e.g. conf/saml-keystore.jks), they just need to be the same as you configure below.

Enable SAML for Stages

To configure, add or enable the following section in conf/config.xml:

<authentication
     enabled="true"
     keystoreFile="/opt/stages/conf/saml-keystore.jks"
     keystorePass="changeit">
   ...
</authentication>

To globally enable SAML, set the enabled attribute to true. The keystore location and password need to match the keystore from above or your SSL server certificate location.

Configure the SAML Service Provider (SP)

The SAML Service Provider describes your local Stages server.

To configure, add or enable the following section in conf/config.xml.

<authentication
     ...

        <service-provider
                        providerId="<yourStagesURL>"
                        keyAlias="samlkeyalias">

        </service-provider>

...

</authentication>

The providerId can be an arbitrary name, but it should be globally unique, so it is a good practice to use your Stages URL.

The keyAlias identifies the key to be used for signing the SAML request, so it needs to match either the key you generated above or your server certificate alias. If it is not set, the SAML request will not be signed.

Generate the SAML SP metadata

After configuring the SAML SP and logged on as root, you can download the SAML SP metadata directly by navigating to the URL https://<yourstages>/stages/rest/saml/metadata

The resulting XML file can be sent to the SAML IdP administrators and contains all information necessary to set up the trust relationship on the IdP side. After the SAML IdP has been configured with the SP metadata, users will be able to authenticate successfully with Stages through the SAML IdP.

Configure the SAML Identity Provider (IdP)

The SAML Identity Provider describes the remote service that Stages uses to authenticate users. Typically, it is run by the access management group within your IT organization.

The most reliable way to configure the SAML Identity Provider (IdP) is to ask the access management team for the IdP metadata.

From this metadata, you will be able to derive the parameters

  • EntityIdfromMetadata
  • DisplayName (alternative: FirstName, LastName)
  • EMailAddress

for the following configuration:

<authentication>
    ...

    <identity-provider
        providerId="<EntityIDfromMetadata>"
        providerUrl="<SingleSignOnServiceLocationFromMetadata>"
        nameIdPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
        sendBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
        userFullnameTemplate="%firstname% %lastname%">

        <!-- userFullnameTemplate is used to build the user's full name from multiple IDP attributes
             as defined below as <identity-provider-attribute name=.../>.
             In the example above the firstname and lastname attributes are concatenated speparated by a space. -->

        <!-- hardcoded magic value that specifies the NameID from the SAML reply -->
        <identity-provider-attribute name="username" id="http://schemas.stages.methodpark.com/saml/v2/identity/claims/subject" />

        <!-- either "fullname" or "firstname" and "lastname" need to be defined -->
        <!--<identity-provider-attribute name="fullname" id="<DisplayName>" />-->
        <identity-provider-attribute name="firstname" id="<FirstName>" />
        <identity-provider-attribute name="lastname" id="<LastName>" />

        <identity-provider-attribute name="email" id="<EMailAddress>" />

        <!-- This matches if the SAML assertion contains a SAML attribute "Organization" with value "External" -->
        <!--
        <identity-provider-attribute-match
            id="Organization"
            pattern="External"
            defaultRolesUsername="default_supplier"
            defaultLicenseType="DEV"
            licensePoolIdent=""
            autocreateUser="true"
                    />
        -->

        <!-- This is the default matcher, identified by id and pattern attributes set to "*" -->
        <identity-provider-attribute-match
            id="*"
            pattern="*"
            defaultRolesUsername="default"
            defaultLicenseType="QM"
            licensePoolIdent=""
            autocreateUser="true"
        />

        <!--
            Specifying at least one signing certificate automatically enables
            signature verification of the authentication response.
            The key data can also be copied from the IdP metadata.
            If no signing certificate is specified, no signature
            validation will be performed.
        -->
        <certificate use="signing">${saml.idp.signatureCertificate}
MIIDCTCC...

       <Insert the X509Certificate "signing" key from the metadata here>

...Qwgf5bXby+ug==
        </certificate>

        <!--
             In case the IDP only provides encrypted assertions specify
             encryption certifacte. The key data can also be copied from the
             IdP metadata. If no encryption certificate is specified, no encrypted
             assertion can be accepted. -->
        <certificate use="''encryption''">
MIIDCTCC...

        <Insert the X509Certificate "encryption" key from the metadata here>

...Qwgf5bXby+ug== </certificate>
        </certificate>
    </identity-provider>

    <!--
        This identity provider statement with the "STAGES"
        magic id enables local Stages logins to be available
        for selection between multiple identity providers
        (NOT IMPLEMENTED YET).
        If the authentication with the IdP fails and the "STAGES"
        provider is enabled, the Stages login screen is shown, so
        the user may log in with a local user id. If it is not
        configured, the server answers with a 403 (Forbidden)
        status code.
    -->
    <identity-provider providerId="STAGES"/>
</authentication>

After you configured the service provider and identity provider in config.xml, update the configuration via “stages update” and restart the Stages service.

Changing the license pool and license type for existing users

By default, existing users are not modified by the SAML authentication process when the SAML configuration was changed after the user had been created. However, you can set the forceLicensePoolReassignment attribute on an identity-provider-attribute-match to true if you want changes of the licensePoolIdent or defaultLicenseType attributes to be applied to existing users.

Configuring Stages attributes in default-matcher section with JavaScript

JavaScript control flow statements (e.g. “if”,“switch”) can be used to configure values for Stages attributes. All assertion attributes of the SAML response are accessible as variables and can be used in the JavaScript expression

JavaScript expressions can be used with the following Stages attributes:

  • defaultRolesUsername
  • defaultLicenseType
  • licensePoolIdent

General JavaScript expression notation:

<Stages_attribute>="=<JavaScript_expression>"

JavaScript notation of if-clauses:

if (condition1) 'returnValue1';
else if (condition2) 'returnValue2';
else if (condition3) 'returnValue3';
else 'returnValue4';

JavaScript notation of value conditions:

SAML Attributes that are defined via identity_provider_attribute elements can be used in these scripts. E.g.

<identity-provider-attribute name="email" id="<EMailAddress>" />
Attribute contains value:
<saml_attribute_id>.match(/.*value/)         // <= 7.9.10.0, <= 7.10.1.0
<saml_attribute_name>.match(/.*value/)       //> 7.9.10.0,> 7.10.1.0

Attribute equals value:

<saml_attribute_id>=="value                 // <= 7.9.10.0, <= 7.10.1.0
<saml_attribute_name>=="value               //> 7.9.10.0,> 7.10.1.0

Example configuration:

This example creates Stages users with the following conditions:

  • The pattern matches the entry of the SAML attribute “id”.
  • Depending on the users' email address (domain-part), SAML attribute name “email” is used to assign different values for defaultRolesUsername, defaultLicenseType and licensePoolIdent
<identity-provider-attribute-match
     id="<saml_attribute_id>"
     pattern="<matching_value>"
     defaultRolesUsername="=
        if (email.match(/.*@company1.com/)) 'User1';
        else if (email.match(/.*@company2.com/)) 'User2';
        else 'default';
        "
     defaultLicenseType="=
        if (email.match(/.*@company1.com/)) 'QM';
        else if (email.match(/.*@company2.com/)) 'PM';
        else 'none';
        "
     licensePoolIdent="=
          if (email.match(/.*@company2.com/)) 'company2';
        else '';
        "
     autocreateUser="true"
/>

Please note that the values of multi value attributes are provided to the scripts as one value as a comma separated string.

Configure the SAML Request Type

The default binding type of the SAML Request is redirect.

Some IDPs do not work with that type and rather need a POST Request. This can only be found out on the IDP.

This can be configured in the identity-provider section via

sendBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"

Validated IdP Vendors

Stages SAML has successfully been deployed with the following IdP servers:

  • Azure AD IdP
  • Okta
  • JumpCloud
  • Cisco Central Web Authentication (CWA)
  • Oracle Access Manager (OAM)
  • Shibboleth IdP
  • Active Directory Federation Services (ADFS)

Please let us know if you were able to make Stages SAML work with your server and it is not on this list yet.