# 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](https://en.wikipedia.org/wiki/SAML_2.0#Web_browser_SSO_profile) 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.

- Configure the [IQ Server's Base URL](https://help.sonatype.com/en/configuring-base-url.html "Configuring Base URL") property before you begin.

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

- Download the provider's [SAML Metadata](http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf) 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

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.

To redirect the authentication to the SAML provider and skip the Sign-in dialog box, you can use the [Configuration REST API](https://help.sonatype.com/en/configuration-rest-api.html "Configuration REST API") (recommended) or set the environment variable as shown below:

```
export NXIQ_ENABLE_SSO_ONLY=true
```

NOTE: Setting the environment variable will require a re-start of the IQ Server.

The Sign-in Dialog box to log in to _Lifecycle_ will not appear and you can continue with the login process as supported by your identity provider.

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.

- #### 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)

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](https://help.sonatype.com/en/configuring-base-url.html "Configuring 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](https://help.sonatype.com/en/iq-server-user-tokens.html "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.

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.

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](https://help.sonatype.com/en/authorization-configuration-rest-api.html "Authorization Configuration REST API").

**Note**

Role assignments for SAML users are configured separately. See [Role Management](https://help.sonatype.com/en/role-management.html#role-management) for more details on assigning roles after SAML setup.

## 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.

## [Identity Provider's SAML Metadata file Example](https://help.sonatype.com/en/saml-integration.html#identity-provider-s-saml-metadata-file-example_body)

The [example metadata](https://docs.oracle.com/en/cloud/saas/field-service/faadu/c-sampleMetadataXML.html) 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>MIID7TCCAtWgAwIBAgIJANn3qP9lF7M3MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJVQTEXMBUGA1UECAwOS2hhcmtpdiBSZWdpb24xEDAOBgNVBAcMB0toYXJrb3YxDzANBgNVBAoMBk9yYWNsZTEYMBYGA1UEAwwPc3RzeWJvdi12bTEudWEzMScwJQYJKoZIhvcNAQkBFhhzZXJnaWkudHN5Ym92QG9yYWNsZS5jb20wHhcNMTUxMjI1MTIyMjU5WhcNMjUxMjI0MTIyMjU5WjCBjDELMAkGA1UEBhMCVUExFzAVBgNVBAgMDktoYXJraXYgUmVnaW9uMRAwDgYDVQQHDAdLaGFya292MQ8wDQYDVQQKDAZPcmFjbGUxGDAWBgNVBAMMD3N0c3lib3Ytdm0xLnVhMzEnMCUGCSqGSIb3DQEJARYYc2VyZ2lpLnRzeWJvdkBvcmFjbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw4OFwuUNjn6xxb/OuAnmQA6mCWPY2hKMoOz0cAajUHjNZZMwGnuEeUyPtEcULfz2MYo1yKQLxVj3pY0HTIQAzpY8o+xCqJFQmdMiakbPFHlh4z/qqiS5jHng6JCeUpCIxeiTG9JXVwF1ErBEZbwZYjVxa6S+0grVkS3YxuH4uTyqxskuGnHK/AviTHLBrLfSrbFKYuQUrXyy6X22wpzobQ3Z+4bhEE8SXQtVbQdy7K0MKWYopNhX05SMTv7yMfUGp8EkGNyJ5Km8AuQt6ZCbVao6cHL2hSujQiN6aMjKbdzHeA1QEicppnnoG/Zefyi/okWdlLAaLjcpYrjUSWQJZQIDAQABo1AwTjAdBgNVHQ4EFgQUIKa0zeXmAJsCuNhJjhU0o7KiQgYwHwYDVR0jBBgwFoAUIKa0zeXmAJsCuNhJjhU0o7KiQgYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAJawU5WRXqkW4emm+djpJAxZ0076qPgEsaaog6ng4MLAlU7RmfIY/l0VhXQegvhIBfG4OfduuzGaqd9y4IsQZFJ0yuotl96iEVcqg7hJ1LEY6UT6u6dZyGj1a9I6IlwJm/9CXFZHuVqGJkMfQZ4gaunE4c5gjbQA5/+PEJwPorKn48w8bojymV8hriqzrmaP8eQNuZUJsJdnKENOE5/asGyj+R2YfP6bmlOX3q0ozLcyJbXeZ6IvDFdRiDH5wO4JqW/ujvdvC553yCO3xxsorB4xCupuHu/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>MIID7TCCAtWgAwIBAgIJANn3qP9lF7M3MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJVQTEXMBUGA1UECAwOS2hhcmtpdiBSZWdpb24xEDAOBgNVBAcMB0toYXJrb3YxDzANBgNVBAoMBk9yYWNsZTEYMBYGA1UEAwwPc3RzeWJvdi12bTEudWEzMScwJQYJKoZIhvcNAQkBFhhzZXJnaWkudHN5Ym92QG9yYWNsZS5jb20wHhcNMTUxMjI1MTIyMjU5WhcNMjUxMjI0MTIyMjU5WjCBjDELMAkGA1UEBhMCVUExFzAVBgNVBAgMDktoYXJraXYgUmVnaW9uMRAwDgYDVQQHDAdLaGFya292MQ8wDQYDVQQKDAZPcmFjbGUxGDAWBgNVBAMMD3N0c3lib3Ytdm0xLnVhMzEnMCUGCSqGSIb3DQEJARYYc2VyZ2lpLnRzeWJvdkBvcmFjbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw4OFwuUNjn6xxb/OuAnmQA6mCWPY2hKMoOz0cAajUHjNZZMwGnuEeUyPtEcULfz2MYo1yKQLxVj3pY0HTIQAzpY8o+xCqJFQmdMiakbPFHlh4z/qqiS5jHng6JCeUpCIxeiTG9JXVwF1ErBEZbwZYjVxa6S+0grVkS3YxuH4uTyqxskuGnHK/AviTHLBrLfSrbFKYuQUrXyy6X22wpzobQ3Z+4bhEE8SXQtVbQdy7K0MKWYopNhX05SMTv7yMfUGp8EkGNyJ5Km8AuQt6ZCbVao6cHL2hSujQiN6aMjKbdzHeA1QEicppnnoG/Zefyi/okWdlLAaLjcpYrjUSWQJZQIDAQABo1AwTjAdBgNVHQ4EFgQUIKa0zeXmAJsCuNhJjhU0o7KiQgYwHwYDVR0jBBgwFoAUIKa0zeXmAJsCuNhJjhU0o7KiQgYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAJawU5WRXqkW4emm+djpJAxZ0076qPgEsaaog6ng4MLAlU7RmfIY/l0VhXQegvhIBfG4OfduuzGaqd9y4IsQZFJ0yuotl96iEVcqg7hJ1LEY6UT6u6dZyGj1a9I6IlwJm/9CXFZHuVqGJkMfQZ4gaunE4c5gjbQA5/+PEJwPorKn48w8bojymV8hriqzrmaP8eQNuZUJsJdnKENOE5/
asGyj+R2YfP6bmlOX3q0ozLcyJbXeZ6IvDFdRiDH5wO4JqW/ujvdvC553yCO3xxsorB4xCupuHu/c7vkzNpaKjYdmGRkqhEqBcCqYSxdwIFc1xhOwYPWKJzgn7pGQsT7yNJg==</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>
```

## [SAML Request Example](https://help.sonatype.com/en/saml-integration.html#saml-request-example_body)

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>
```

## [SAML Response Example](https://help.sonatype.com/en/saml-integration.html#saml-response-example-162325_body)

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>
```

## Search results

No results found
