# SAML

Only available in Sonatype Nexus RepositoryTM Pro. Interested in a free trial? [Start here](/content/products/repository-pro/trial/index.html).

You can configure your instance to work with a SAML Identity Provider for authentication via Single Sign-On (SSO) and to send user groups to it for authorization. Nexus Repository implements the Web Browser SSO Profile from the [SAML 2.0 specification](http://docs.oasis-open.org/security/saml/v2.0/). Supported bindings for sign-on are HTTP-POST (the default) and HTTP-Redirect for requests to the Identity Provider and HTTP-POST binding for responses from the Identity Provider. The Basic Attribute Profile is used for retrieving further information regarding the subjects and supported attributes are explained in [SAML Configuration Details](https://help.sonatype.com/en/saml.html#saml-configuration-details "SAML Configuration Details").

SAML provides access to the UI. For clients that don't support SSO, Nexus Repository can generate user tokens, which can be used instead of a user name and password for basic authentication or to make REST API calls.

**SAML login requires SAML2_AUTH_REQUEST cookie beginning in release 3.89.0**

Starting in Sonatype Nexus Repository 3.89.0-09, SAML authentication requires the SAML2_AUTH_REQUEST cookie to complete the login flow.

## Tested SAML Providers and Minimal XML for Untested SAML Providers

We have tested the following providers with SAML and Nexus Repository: **Auth0, Azure AD, Keycloak, Okta, OneLogin, PingFederate**.

Below is a minimal XML example to help users with un-tested providers get SAML working. The following XML replaced some values with placeholders but demonstrates a simplified SAML XML:

```
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="id" entityID="https://sts.windows.net/hash/">
  <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <KeyDescriptor use="signing">
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
          <X509Certificate>
            certificate goes here
          </X509Certificate>
        </X509Data>
      </KeyInfo>
    </KeyDescriptor>
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.microsoftonline.com/hash/saml2"/>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.microsoftonline.com/hash/saml2"/>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://login.microsoftonline.com/hash/saml2"/>
  </IDPSSODescriptor>
</EntityDescriptor>
```

If you receive an "Invalid SAML metadata” error, try reducing the XML metadata to just the tags shown in the minimal example above.

## Integrating with an Identity Provider

Configuring SAML requires the _nx-all_ privilege and the following steps:

1. Download the Identity Provider's [SAML metadata](http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf) file. This file may appear similar to the example below, which uses Keycloak as the Identity Provider:

```
<md:EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://localhost:8080/auth/realms/demo">
<md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:KeyName>Example_KeyName_Nexus</ds:KeyName>
<ds:X509Data>
<ds:X509Certificate>Example_Certificate_Data</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/auth/realms/demo/protocol/saml/resolve" index="0"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/auth/realms/demo/protocol/saml"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/auth/realms/demo/protocol/saml"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://localhost:8080/auth/realms/demo/protocol/saml"/>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/auth/realms/demo/protocol/saml"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/auth/realms/demo/protocol/saml"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/auth/realms/demo/protocol/saml"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://localhost:8080/auth/realms/demo/protocol/saml"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>
```

2. In Nexus Repository, [upload the Identity Provider metadata](https://help.sonatype.com/en/saml.html#uploading-the-identity-provider-metadata-and-configuring-the-attribute-names-using-the-ui "Uploading the Identity Provider Metadata and Configuring the Attribute Names Using the UI").

3. Download Nexus Repository's SAML metadata (also known as the service provider metadata) to provide to the Identity Provider. Note that some Identity Providers may be configured differently. It can be downloaded with the SAML REST API:

```
curl -u admin:admin123 -X GET "http://localhost:8081/service/rest/v1/security/saml/metadata"
```

4. If applicable, upload Nexus Repository's SAML metadata (downloaded in the previous step) to the Identity Provider.  
   - This is also referred to as registering a service provider to an Identity Provider.  
   - If the Identity Provider does not allow uploading Nexus Repository's SAML metadata, then you can inspect it to extract the needed values. Also note that the "Audience" of your Identity Provider should be Nexus Repository's Entity ID, and its "Recipient" should be Nexus Repository's assertion consumer service URL. Please note that Nexus Repository's assertion consumer service URL is `/saml`.

5. Configure the Identity Provider to send expected subject information as basic attributes. Note that these attribute names can be customized later.

6. Enable the SAML Realm in Nexus Repository.

7. Enable User Tokens in Nexus Repository.

Integration is complete and Single Sign-On using SAML is functional.

- As long as a SAML configuration exists and the SAML Realm is enabled, the user will be prompted to _Sign in with SSO_ or _Sign In Without SSO_(the latter for signing in using non-SAML realms).

- If no SAML configuration exists or the SAML Realm is not enabled, the Single Sign-On prompt dialog will not appear.

- When you delete an existing SAML configuration and create a new one, even if you use the same Identity Provider metadata XML, Nexus Repository will generate new keys, requiring SAML metadata XML to be downloaded and re-registered to the Identity Provider.

### Uploading the Identity Provider Metadata and Configuring the Attribute Names Using the UI

- Access the SAML Configuration UI using the _SAML_ item of the _Security_ settings menu.

- When SAML is not configured in Nexus Repository, the _SAML Identity Provider Metadata XML_ will be empty, and the attributes will have their default values populated.

- Upload the Identity Provider's metadata XML by pasting the XML directly in the text area.

- Modify the response/assertion signature validation if needed.

- Modify the Attribute Names if needed.

- Select _Save_.

### Enabling the SAML Authentication Realm

Activate your _SAML Realm_ by following these steps:

- Navigate to _Realms_ in the _Security_ settings menu

- Select the _SAML Realm_ and add it to the list of _Active_ realms on the right

- Ensure that the _SAML Realm_ is located beneath the _Local Authenticating Realm_ in the list

- Select _Save_

Best practice is to leave the _Local Authenticating Realm_ activated so that the repository manager can be used by _anonymous_, _admin_ and other users configured in this realm even with SAML authentication offline or unavailable. When users choose _Sign In Without SSO_, the other realms will be used for authentication, in the order they appear.

### Enabling User Tokens

Activate _User Tokens_ by the following steps:

- Navigate to _User Tokens_ in the _Security_ settings menu.

- Click _Enable User Tokens._

- Press _Save._

The _User Token Realm_ will automatically be added to the active Realms.  
Refer to the section on [User Tokens](https://help.sonatype.com/en/user-tokens.html "User Tokens") for more details.

## SAML Configuration Details

### Entity ID

Entity ID is a unique identifier that will be used when registering Nexus Repository to the Identity Provider as a service provider. It must be a valid URI. The default value `<BaseUrl>`/service/rest/v1/security/saml/metadata is recommended and normally there is no need to modify the Entity ID, but it is required if the deployed instance does not have a fixed URL or port.

### Attribute Names

Nexus Repository expects the following basic SAML attributes to carry/extract the user information:

- username attribute
- first name attribute
- last name attribute
- e-mail attribute
- groups attribute; SAML groups will be mapped to Nexus Repository roles

These attribute names must be configured on the Identity Provider, and must match the SAML Configuration in Nexus Repository. Note that the values are case-sensitive.  
For example, if the Identity Provider sends the email information of a user with the attribute `user-email-address`, please make sure you configure the email attribute name to `user-email-address` in Nexus Repository as well.

All of these properties are optional to configure. If they are not explicitly configured, default values for them will be used.

### Securing SAML Integration

**Note**

From Nexus Repository 3.27, if the SAML assertions are being signed, then the Identity Provider **must** set a destination field in the response that is set to the Nexus Assertion Consumer URL (`<BaseURL>/saml`).

Signed requests and responses between the Identity Provider and Nexus Repository are supported and recommended for security purposes. Signing responses can only be configured from the Identity Provider and not within Nexus Repository. In case signed messages are used and the Identity Provider's signature keys are renewed (or changed for any other reason), Identity Provider metadata in Nexus Repository's SAML configuration must be updated.

Nexus Repository's SAML configuration can be set to validate the Identity Provider's signature(s) on its response and/or its assertions within that response by setting  
- the validate response signature
- the validate assertion signature

options. By default, if a signing key is found in the Identity Provider metadata, then Nexus Repository will attempt to validate signatures on the response and its assertions.

### SAML Response Validation

Starting in Nexus Repository 3.88.0, the SAML library enforces stricter validation of `entityId` values in the SAML response. The following table identifies the XML elements validated against your Nexus Repository configuration:

| SAML Response Element | Validated Against | Description |
| --- | --- | --- |
| `<saml:Audience>` | Entity ID configured in Nexus Repository | The Service Provider (SP) `entityId` the Identity Provider includes in `<saml:AudienceRestriction>`. Must exactly match the Entity ID configured in Nexus Repository. |
| `<saml:Issuer>` | `entityID` in the uploaded Identity Provider metadata | The Identity Provider's identifier. Must match the `entityID` attribute in the IdP's SAML metadata uploaded to Nexus Repository. |

**Note**

Starting in Nexus Repository 3.88.0, both values require exact string matching. A trailing slash difference, which is a common misconfiguration when using Microsoft Entra ID (formerly Azure AD), will cause authentication to fail.

### SAML Response Example

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:8081/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/demo</saml:Issuer>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  </samlp:Status>
  <saml: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/demo</saml:Issuer>
    <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:8081/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:8081/service/rest/v1/security/saml/metadata
        </saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <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">jonny@example.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:Attribute>
    </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>
```

## User SAML Workflow

Once Nexus Repository is configured to use SAML, users can log into the Nexus Repository UI.

- Login can be done using the Identity Provider's login experience by clicking the Single Sign-On button at the user login.

- Once the user logs in to the Identity Provider, they will be redirected back to Nexus Repository with an active session.

- Logging out of Nexus Repository will not invalidate the session on the Identity Provider.

- The user can generate a [user token](https://help.sonatype.com/en/user-tokens.html "User Tokens") to use for secure authentication with format clients.

Below are some additional considerations:

- Format clients like mvn, docker and npm don't support SSO, so users that authenticate with SAML must use user tokens.

- Any existing sessions will not be invalidated once SAML is configured meaning any users already logged in when SAML is configured will need to logout and login again via the Single Sign-On button to use SAML SSO.

- Roles can be assigned to SAML users by a Nexus Repository administrator if additional role based security is required.

After a user has logged into Nexus Repository, they can obtain a user token:

- The user must access the menu by selecting their username on the top right area of the main toolbar and select _User Token_.

- The user must then click _Access User Token._

- The token can then be copied into the configuration file for the format client.

## Revoking User Access

User access is revoked by doing the following:

- Disabling the user in the SAML Identity Provider.

- Revoking user tokens as a Nexus Repository administrator.

To revoke user tokens for all users, you can use either one of the following actions:

- Use the _Revoke all user tokens_ button found under _Settings_ → _Security_ → _User Token._

- Invoke the REST API:

```
curl -u admin:admin123 -X DELETE "http://localhost:8081/service/rest/v1/security/user-tokens"
```

To revoke the user token of a specific user, invoke the user token REST API using the following:

```
curl -u admin:admin123 -X DELETE "http://localhost:8081/service/rest/v1/security/users/{userId}/SamlRealm/user-token-reset"
```

Note that SAML does not allow notification of downstream systems when a user in the identity provider is deactivated. However, as soon as a user is deactivated in the identity provider, they will not be able to log into Nexus Repository using SAML.

If these users have user tokens, those will remain present in Nexus Repository.
