Skip to main content

SAML Integration

Use a SAML Identity Provider (IdP) for authentication through the Single Sign-On (SSO) protocol. IQ Server implements the web browser SSO profile from the SAML 2.0 specification.

Review SAML 2.0 documentation from Wikipedia to learn more about the SAML 2.0 protocol.

Requirements

This process requires a user with the System Administrator role to configure the IQ Server.

You need access to your SAML Identity Provider for the following configuration:

  • Download the provider's SAML Metadata file.

  • Upload the IQ Server's SAML Metadata as a new Service Provider or Client in your IdP.

  • Configure the attribute bindings to map user metadata in the IQ Server.

Adding the SAML Identity Provider

  1. Navigate to the SAML configuration from the system preference menu

  2. Provide a meaningful name for the identity provider as it displays on the login screen

  3. Upload the IdP's SAML Metadata file

  4. Select the Save button at the bottom of the view

iq-config-saml-upload.png

With the SAML configuration set, users log in with the sign-in modal display using the Single Sign-On button. The IQ Server's SAML Metadata must be uploaded before users may log into the service.

iq-config-sso-login.png

Logging out of the IQ Server does not invalidate the session on the Identity Provider.

Existing sessions are not invalidated once SAML is configured. Users logged into the server will need to manually log out before using the SAML SSO.

Configure Attribute Bindings

To display user information correctly, you need to configure the Identity Provider to send user information as basic attributes aligning to the attribute names in the IQ Server. When not configured the default values are used. Attribute names are case-sensitive.

These attribute names may be configured at any time.

iq-config-saml-attributes.png
  • Username attribute

    The username is the unique identifier for the user.

    Default: username

  • first name attribute

    The user's first name for displaying on reports and for searching when setting access control.

    Default: firstName

  • last name attribute

    The user's last name for displaying on reports and for searching when setting access control.

    Default: lastName

  • e-mail attribute

    Required for sending notifications.

    Default: email

  • groups attribute

    List of organizational groups the user belongs to. Ideal for externalizing access controls to the IdP rather than managing individuals in the IQ Server.

    Default: groups

Securing SAML Integration

Signing requests from the Identity Provider is recommended and is configured by the Identity Provider. When a signing key is provided in the Identity Provider's metadata XML, the response and assertion are validated in the IQ Server by default.

  • Validate Response Signature

    Values: Default, true, false

    The Response is the entire SAML message the Identity Provider sends to the IQ Server.

  • Validate Assertion Signature

    Values: Default, true, false

    The Assertions are contained within that response and are what the Identity Provider claims about the user.

The required security keys are included in the IQ Server's SAML Metadata when uploading in the next step.

Upload the IQ Server's SAML Metadata

Before using SAML SSO, the IQ Server needs to be configured as a Service Provider with the Identity Provider. This is done by uploading the IQ Server SAML Metadata as a new client on the IdP.

  1. Select the Download IQ Server Metadata button

  2. Upload IQ Server's SAML Metadata to the Identity Provider

  3. With the SAML configuration set, the user login modal displays a Single Sign-On button.

Entity ID

Entity ID is the unique identifier used when registering IQ Server to the Identity Provider as a Service Provider. This identifier must be a valid URI and use the IQ Server Base URL so that the IdP may locate the IQ Server.

The default value is as follows:

<iqServerBaseUrl>/api/v2/config/saml/metadata

When re-adding the SAML configuration, a new IQ Server Metadata XML file must be downloaded and re-registered with the Identity Provider to register the new security keys.

Supported Bindings

Supported bindings for sign-on are as follows:

  • HTTP-Redirect for requests to the Identity Provider

  • HTTP-POST binding for responses from the Identity Provider

  • Basic Attribute Profile is used for retrieving information on the users

Access the IQ Server Integrations with User Tokens for SAML

SAML users must generate user tokens to access the plug-ins and the IDE integrations. The User Token REST API or UI may be used to create user tokens after the user has logged into the UI at least once.

See IQ Server User Tokens for details.

Sending Notifications by Group with SAML

A common practice when configuring notifications is to set them to an identity provider group to avoid managing users inside the IQ Server. However, the IQ server does not have the means to send members of a group or role notifications when using SAML only for authentication.

The best practice is to include an LDAP connection when using SAML for authentication where the LDAP connection is used to determine the members of groups for authorization.

Many identity providers support configuring with both SAML and LDAP connectors.

For example, you may configure users from a "Team A" group to the Developer role for the organization with the same name.

iq-config-role-developer.png

When configuring notifications for policy violations, you may set the notification to the Developer role and anyone from the group, "Team A", would receive the notification.

iq-config-policy-notification-developer.png

SAML authenticated does not have a means to query for every user in a specific group. The service only knows which groups from which a user is a member after that user first authenticates with the server. When the user's group changes, the IQ server learns of the change the next time they authenticate.

LDAP connections may be queried for all the members of groups making administration for authorization far simpler.

When only SAML is used, authorization is managed using the role membership REST API.

SAML Changelog

  • Release 180 - Java 17 is required to run the IQ Server

    Starting Java version 17 the use of SHA-1-based digests and signature algorithms for XML signatures has been forbidden. Users need to reconfigure the signature algorithm on their identity provider platform.

The example metadata is as follows:

<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php">
  <md:IDPSSODescriptor 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>MIID7TCCAtWgAwIBAgIJANn3qP9lF7M3MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJVQTEXMBUGA1UE
		  CAwOS2hhcmtpdiBSZWdpb24xEDAOBgNVBAcMB0toYXJrb3YxDzANBgNVBAoMBk9yYWNsZTEYMBYGA1UEAwwPc3RzeWJvdi12bTEudWEzMScw
		  JQYJKoZIhvcNAQkBFhhzZXJnaWkudHN5Ym92QG9yYWNsZS5jb20wHhcNMTUxMjI1MTIyMjU5WhcNMjUxMjI0MTIyMjU5WjCBjDELMAkGA1UE
		  BhMCVUExFzAVBgNVBAgMDktoYXJraXYgUmVnaW9uMRAwDgYDVQQHDAdLaGFya292MQ8wDQYDVQQKDAZPcmFjbGUxGDAWBgNVBAMMD3N0c3lib
		  3Ytdm0xLnVhMzEnMCUGCSqGSIb3DQEJARYYc2VyZ2lpLnRzeWJvdkBvcmFjbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCA
		  QEAw4OFwuUNjn6xxb/OuAnmQA6mCWPY2hKMoOz0cAajUHjNZZMwGnuEeUyPtEcULfz2MYo1yKQLxVj3pY0HTIQAzpY8o+xCqJFQmdMiakb
		  PFHlh4z/qqiS5jHng6JCeUpCIxeiTG9JXVwF1ErBEZbwZYjVxa6S+0grVkS3YxuH4uTyqxskuGnHK/AviTHLBrLfSrbFKYuQUrXyy6X22wpzo
		  bQ3Z+4bhEE8SXQtVbQdy7K0MKWYopNhX05SMTv7yMfUGp8EkGNyJ5Km8AuQt6ZCbVao6cHL2hSujQiN6aMjKbdzHeA1QEicppnnoG/Zefyi/
		  okWdlLAaLjcpYrjUSWQJZQIDAQABo1AwTjAdBgNVHQ4EFgQUIKa0zeXmAJsCuNhJjhU0o7KiQgYwHwYDVR0jBBgwFoAUIKa0zeXmAJsCuNhJj
		  hU0o7KiQgYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAJawU5WRXqkW4emm+djpJAxZ0076qPgEsaaog6ng4MLAlU7RmfIY/
		  l0VhXQegvhIBfG4OfduuzGaqd9y4IsQZFJ0yuotl96iEVcqg7hJ1LEY6UT6u6dZyGj1a9I6IlwJm/9CXFZHuVqGJkMfQZ4gaunE4c5gjbQA5/
		  +PEJwPorKn48w8bojymV8hriqzrmaP8eQNuZUJsJdnKENOE5/asGyj+R2YfP6bmlOX3q0ozLcyJbXeZ6IvDFdRiDH5wO4JqW/ujvdvC553y
		  CO3xxsorB4xCupuHu/c7vkzNpaKjYdmGRkqhEqBcCqYSxdwIFc1xhOwYPWKJzgn7pGQsT7yNJg==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>MIID7TCCAtWgAwIBAgIJANn3qP9lF7M3MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJVQTEXMBUGA1
		  UECAwOS2hhcmtpdiBSZWdpb24xEDAOBgNVBAcMB0toYXJrb3YxDzANBgNVBAoMBk9yYWNsZTEYMBYGA1UEAwwPc3RzeWJvdi12bTEud
		  WEzMScwJQYJKoZIhvcNAQkBFhhzZXJnaWkudHN5Ym92QG9yYWNsZS5jb20wHhcNMTUxMjI1MTIyMjU5WhcNMjUxMjI0MTIyMjU5WjCB
		  jDELMAkGA1UEBhMCVUExFzAVBgNVBAgMDktoYXJraXYgUmVnaW9uMRAwDgYDVQQHDAdLaGFya292MQ8wDQYDVQQKDAZPcmFjbGUxGDA
		  WBgNVBAMMD3N0c3lib3Ytdm0xLnVhMzEnMCUGCSqGSIb3DQEJARYYc2VyZ2lpLnRzeWJvdkBvcmFjbGUuY29tMIIBIjANBgkqhkiG9w0B
		  AQEFAAOCAQ8AMIIBCgKCAQEAw4OFwuUNjn6xxb/OuAnmQA6mCWPY2hKMoOz0cAajUHjNZZMwGnuEeUyPtEcULfz2MYo1yKQLxVj3pY0HT
		  IQAzpY8o+xCqJFQmdMiakbPFHlh4z/qqiS5jHng6JCeUpCIxeiTG9JXVwF1ErBEZbwZYjVxa6S+0grVkS3YxuH4uTyqxskuGnHK/
		  AviTHLBrLfSrbFKYuQUrXyy6X22wpzobQ3Z+4bhEE8SXQtVbQdy7K0MKWYopNhX05SMTv7yMfUGp8EkGNyJ5Km8AuQt6ZCbVao6cHL2h
		  SujQiN6aMjKbdzHeA1QEicppnnoG/Zefyi/okWdlLAaLjcpYrjUSWQJZQIDAQABo1AwTjAdBgNVHQ4EFgQUIKa0zeXmAJsCuNhJjhU0o
		  7KiQgYwHwYDVR0jBBgwFoAUIKa0zeXmAJsCuNhJjhU0o7KiQgYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAJawU5WRXq
		  kW4emm+djpJAxZ0076qPgEsaaog6ng4MLAlU7RmfIY/l0VhXQegvhIBfG4OfduuzGaqd9y4IsQZFJ0yuotl96iEVcqg7hJ1LEY6UT6u6d
		  ZyGj1a9I6IlwJm/9CXFZHuVqGJkMfQZ4gaunE4c5gjbQA5/+PEJwPorKn48w8bojymV8hriqzrmaP8eQNuZUJsJdnKENOE5/
		  asGyj+R2YfP6bmlOX3q0ozLcyJbXeZ6IvDFdRiDH5wO4JqW/ujvdvC553yCO3xxsorB4xCupuHu/c7vkzNpaKjYdmGRkqhEqBcCqYSxd
		  wIFc1xhOwYPWKJzgn7pGQsT7yNJg==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp-saml.ua3.int/simplesaml/saml2/idp/SingleLogoutService.php"/>
    <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
    <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp-saml.ua3.int/simplesaml/saml2/idp/SSOService.php"/>
  </md:IDPSSODescriptor>
  <md:ContactPerson contactType="technical">
    <md:SurName>Administrator</md:SurName>
    <md:EmailAddress>name@emailprovider.com</md:EmailAddress>
  </md:ContactPerson>
</md:EntityDescriptor>

A SAML Request from IQ Server will have the following form:

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns="urn:oasis:names:tc:SAML:2.0:assertion" 
    Destination="http://localhost:8080/auth/realms/master/protocol/saml" ForceAuthn="false" ID="ID_a6998aaa-5136-43e8-9f4f-dfff023509c8" 
    IsPassive="false" IssueInstant="2019-09-09T15:26:05.647Z" Version="2.0">
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8070/api/v2/config/saml/metadata</saml:Issuer>
    <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        <dsig:SignedInfo>
            <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
            <dsig:Reference URI="#ID_a6998aaa-5136-43e8-9f4f-dfff023509c8">
                <dsig:Transforms>
                    <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                    <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                </dsig:Transforms>
                <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <dsig:DigestValue>...</dsig:DigestValue>
            </dsig:Reference>
        </dsig:SignedInfo>
        <dsig:SignatureValue>...</dsig:SignatureValue>
        <dsig:KeyInfo>...</dsig:KeyInfo>
    </dsig:Signature>
    <samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>
</samlp:AuthnRequest>

A SAML Response from the Identity Provider will have the following form:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="http://localhost:8070/saml" ID="ID_8c7224bc-a04d-43d8-8fb7-02747425b6d2" InResponseTo="ID_a6998aaa-5136-43e8-9f4f-dfff023509c8" IssueInstant="2019-09-09T15:27:33.971Z" Version="2.0">
    <saml:Issuer>http://localhost:8080/auth/realms/master</saml:Issuer>
    <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        <dsig:SignedInfo>
            <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
            <dsig:Reference URI="#ID_8c7224bc-a04d-43d8-8fb7-02747425b6d2">
                <dsig:Transforms>
                    <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                    <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                </dsig:Transforms>
                <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <dsig:DigestValue>...</dsig:DigestValue>
            </dsig:Reference>
        </dsig:SignedInfo>
        <dsig:SignatureValue>...</dsig:SignatureValue>
        <dsig:KeyInfo>...</dsig:KeyInfo>
    </dsig:Signature>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="ID_526c9596-fedb-4909-ab27-7b15d5692c53" IssueInstant="2019-09-09T15:27:33.971Z" Version="2.0">
        <saml:Issuer>http://localhost:8080/auth/realms/master</saml:Issuer>
        <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
            <dsig:SignedInfo>
                <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                <dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <dsig:Reference URI="#ID_526c9596-fedb-4909-ab27-7b15d5692c53">
                    <dsig:Transforms>
                        <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                        <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    </dsig:Transforms>
                    <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                    <dsig:DigestValue>...</dsig:DigestValue>
                </dsig:Reference>
            </dsig:SignedInfo>
            <dsig:SignatureValue>...</dsig:SignatureValue>
            <dsig:KeyInfo>...</dsig:KeyInfo>
        </dsig:Signature>
        <saml:Subject>
            <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">nameId</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml:SubjectConfirmationData InResponseTo="ID_a6998aaa-5136-43e8-9f4f-dfff023509c8" NotOnOrAfter="2019-09-09T15:28:31.971Z" Recipient="http://localhost:8070/saml"/>
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions NotBefore="2019-09-09T15:27:31.971Z" NotOnOrAfter="2019-09-09T15:28:31.971Z">
            <saml:AudienceRestriction>
                <saml:Audience>http://localhost:8070/api/v2/config/saml/metadata</saml:Audience>
            </saml:AudienceRestriction>
        </saml:Conditions>
        <saml:AuthnStatement AuthnInstant="2019-09-09T15:27:33.971Z" SessionIndex="4517351d-1303-4208-935d-852944760239::e1f45bba-dfac-4294-bbc2-7020da66a3a4">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
        <saml:AttributeStatement>
            <saml:Attribute FriendlyName="username" Name="username" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">jonny</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute FriendlyName="firstName" Name="firstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">John</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute FriendlyName="lastName" Name="lastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Smith</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute FriendlyName="email" Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">john@smith.com</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute FriendlyName="groups" Name="groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">group1</saml:AttributeValue>
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">group2</saml:AttributeValue>
                ...
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">groupN</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>