# Setting up single sign-on with Azure Active Directory

This article takes an administrator through the process of setting up Single Sign-On (SSO) with Azure Active Directory (AD). It uses Security Assertion Markup Language (SAML) for authentication.

## Create an app in the Azure portal

1. Navigate to the **Azure Active Directory** service.
2. Select **Enterprise applications** from the Manage menu on the left.
3. Select **New Application**, then **Create your own application**.
4. Give your application a name and select **Integrate any other application you don't find in the gallery (Non-gallery)**. Select **Create**.
5. Wait while the system creates the application.

### Configure SAML for the app

1. From the list of applications, select the name of the application you created.
2. Select **Set up single sign on**, then **SAML** to open the **Set up Single Sign-On with SAML** page.
3. Edit the **Basic SAML Configuration** with the following values (substitute your actual server address for the placeholder):

   | Configuration item | Value |
   | --- | --- |
   | Identifier (Entity ID) | `https://AptecoLoginAPI/` |
   | Reply URL (Assertion Consumer Service URL) | `https://[your-server]/OrbitAPI/ExternalLogin/AssertionConsumerService/` |
   | Sign on URL | `https://[your-server]/OrbitAPI/ExternalLogin/AssertionConsumerService/` |
   | Relay State (Optional) | `https://[your-server]/Orbit/external-login/` |
4. Select **Save**.
5. From section **3 SAML Certificates**, download the **Certificate (Base64)**. You may choose to name it `Azure.cer`.
6. From section **4 Set up (app)**, copy the:

   - **Login URL**: `https://login.microsoftonline.com/[GUID]/saml2`
   - **Azure AD Identifier**: `https://sts.windows.net/[GUID]/`

   Substitute your actual Azure GUID into these URLs.

## Configure the Orbit Login Service

See [Orbit login service](<https://help.apteco.com/en/admin/configuration/single-sign-on/login-service/index.md>) to install and configure the Login Service first.

1. Move the downloaded certificate to the certificates folder:

   Text Only

   ```text
   C:\Program Files (x86)\Apteco\OrbitLoginService\Certificates\Azure.cer
   ```
2. Edit the Orbit Login Service configuration file with the following JSON:

   JSON

   ```json
   {
     "Serilog": {
       "MinimumLevel": {
         "Default": "Debug",
         "Override": {
           "Microsoft": "Debug",
           "System": "Debug",
           "ComponentSpace.Saml2": "Debug"
         }
       },
       "WriteTo": [
         { "Name": "Trace" },
         {
           "Name": "RollingFile",
           "Args": { "pathFormat": "C:\\temp\\Orbit\\Logs\\OrbitLogin-{Date}.txt" }
         }
       ],
       "Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"]
     },
     "Kestrel": {
       "Endpoints": {
         "Http": { "Url": "http://localhost:5005" }
       }
     },
     "AllowedHosts": "*",
     "SAML": {
       "$schema": "https://www.componentspace.com/schemas/saml-config-schema-v1.0.json",
       "Configurations": [
         {
           "LocalServiceProviderConfiguration": {
             "Name": "https://AptecoLoginApi/",
             "Description": "Apteco Orbit Login API",
             "AssertionConsumerServiceUrl": "https://example.com/OrbitAPI/ExternalLogin/AssertionConsumerService",
             "LocalCertificates": [
               { "FileName": "certificates/sp.pfx", "Password": "password" }
             ]
           },
           "PartnerIdentityProviderConfigurations": [
             {
               "Name": "https://sts.windows.net/<GUID>/",
               "Description": "Azure",
               "SignAuthnRequest": true,
               "SingleSignOnServiceUrl": "https://login.microsoftonline.com/<GUID>/saml2",
               "PartnerCertificates": [
                 { "FileName": "certificates/Azure.cer" }
               ]
             }
           ]
         }
       ]
     },
     "PartnerName": "https://sts.windows.net/<GUID>/",
     "JWT": {
       "Key": "VerySecretSecurityJWTKey",
       "Issuer": "https://AptecoLoginApi/"
     },
     "AllowedReturnUrlOrigins": "https://example.com/"
   }
   ```

   Substitute `<GUID>` with your actual Azure GUID. The following parameters are unique to your Azure instance:

   | Parameter | Azure value |
   | --- | --- |
   | `SingleSignOnServiceUrl` | Login URL from Azure |
   | `PartnerCertificates.FileName` | Filename of the certificate (e.g. `certificates/Azure.cer`) |
   | `AllowedReturnUrlOrigins` | Base address of the website hosting Orbit |

## Add users to the Azure application

Add users to the Azure application using the email address associated with the Apteco system.

1. In Azure AD, select **\+Add** \> **User**.
2. Choose **Create user** or **Invite user**, and enter the user's details including email address. Invited users receive an email from `invites@microsoft.com` with a link to connect with the new application.

### Assign users to the app

1. From **Enterprise applications**, choose the application you created.
2. Select **Assign users and groups**.
3. Select **\+Add user/group**.
4. Choose **Users (None Selected)** to open the Users panel, select the user to add, then confirm with **Select**.
5. Select **Assign**.

## Troubleshooting

### Logging in causes a "no dataview" error

When logging in, Orbit displays the following error:

Azure passes `User.userprincipalname` instead of the user's email address, which causes this error.

1. Log in to [portal.azure.com](<https://portal.azure.com>).
2. Select **Azure Active Directory** \> **Enterprise Applications** \> **Your Application**.
3. Select **Set up single sign on**.
4. In **Attributes &amp; Claims**, select **Edit**.
5. Select the default claim name (`user.userprincipalname`) to edit it.
6. Change **Source Attribute** to `user.mail` and select **Save**.

When the user refreshes their browser, they will be able to sign in.
