# Microsoft Entra ID (Azure AD) as SAML IDP for SSO

# Preamble

The EE server and client support the SAML protocol that allows you to configure an external service as IDP (identity provider) for SSO (single sign on). This guide here will explain how to configure Microsoft Entra ID (Azure AD) as SAML IDP for SSO. We assume that your server can firewall / network wise access Microsoft Entra ID (Azure AD) . In addition we assume that your webclient is running on https://example.com, the server is reachable with https://example.com/server (e.g. https://example.com/server/info/ shows you some nice json output). This is your first SAML provider that you want to configure (therefore we give him the ID "1"). Microsoft Entra ID (Azure AD) allows up to 10 SSO Applications in all versions. Also if you are using Office 365 it is included. (See: microsoft.com/en-gb/security/business/microsoft-entra-pricing (opens new window))

TIP

This feature is only available in the Enterprise Edition.

# Azure Active Directory

As a first step we have to configure Azure Active Directory.

  1. Enable Microsoft Entra ID (Azure AD) SSO

    Go to your Microsoft Entra ID (Azure AD) Enterprise Applications (opens new window).

    Enable Microsoft Entra ID (Azure AD) SSO

  2. Create Application

    Click on "New Application" and choose "Non-gallery application". Select a Name and click on "Add".

    Create Application

    TIP

    If you choose an other Name except 'Psono', you need to configure this in the settings.yaml

  3. Configure Application Permissions

    Click on "1. Assign users and groups" to assign Users or security groups (Office 365 Groups aren't working) to access Psono via SAML.

    Configure Application Permissions

  4. Configure SAML on the Application

    Click on "2. Set up single sign on" and then choose "SAML".

    Configure SAML on the Application Step 1

  5. Basic SAML Configuration

    Configure the URLs as shown in the picture below.

    Configure SAML on the Application Step 2

  6. User Attributes & Claimes

    Configure the "User Attributes & Claims"

    Configure SAML on the Application Step 2

    And adjust them as shown below:

    Configure Azure claims

    Configure group claim with "Add a group claim":

    Configure Azure claims

    WARNING

    Azure won't add more than 150 groups to a SAML response. If your user's might have that limit, you need to limit the amount of groups.

  7. SAML Signing Certificate

    Download Azure's idp certificate in Base64 as shown below:

    Configure SAML on the Application Step 2

    WARNING

    If you ever go back and modify the claims or the URLs in the "Basic SAML Configuration", then Azure will generate a new certificate which you have to download and use.

  8. Copy Azure URLs

    Take note of these two URLs as we will need them in a minute.

    Configure SAML on the Application Step 2

  9. Go to App registrations

    As a next step we need to create some API credentials to translate the group ids to readable names. So please go to "App registrations"

    Go to App registrations

  10. Select new application

    Click on "All applications" and select the created application

    Select application

  11. Create new API Permission

    In the left menu click on "API permissions" and then "Add a permission"

    Create new API Permission

  12. Select "Microsoft Graph"

    Microsoft Graph

  13. Select "Application permissions"

    Application permissions

  14. Choose "Directory.Read.All"

    Search for "Directory.Read.All", check it, and then click on "Add permission" at the bottom.

    Add a permission

    An administrator now needs to grant the permission. If you are an administrator, you can click on "Grant admin consent for ...". The status should flip to "Granted" .

    Add a permission

  15. Create new client secret

    On the left side click on "Certificates & secrets" and then "New client secret"

    Add a permission

    Enter a descriptive name and choose an expiration date.

    Configure new client secret

    Copy the "Value" of the new client secret. We will need it later and it won't be displayed again.

    Configure new client secret

  16. Go to "Overview"

Go to overview and take a copy of the "Application (client) ID" and the "Directory (tenant) ID"

App registrations overview

# Server (settings.yaml)

During the installation of the server you have created a settings.yaml that needs to be adjusted now.

  1. Generate SP certificate

    You will need a certificate for your service provider (SP) later. You can generate one easily with:

    openssl req -new -newkey rsa:2048 -x509 -days 3650 -nodes -sha256 -out sp_x509cert.crt -keyout sp_private_key.key
    

    This will generate a private key (sp_private_key.key) and the public certificate (sp_x509cert.crt).

  2. Change or add SAML configuration in to settings.yaml.

    SAML_CONFIGURATIONS:
        1:
            idp:
                entityId: "REPLACE_WITH_AZURE_AD_IDENTIFIER"
                singleLogoutService:
                    binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                    url: "https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0"
                singleSignOnService:
                    binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                    url: "REPLACE_WITH_LOGIN_URL"
                x509cert: "CERT_FROM_AZURE_APPLICATION"
                groups_attribute: "groups"
                username_attribute: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
                email_attribute: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
                username_domain: "USER_DOMAIN"
                required_group: []
                is_adfs: true
                honor_multifactors: true
                max_session_lifetime: 43200
                azure_client_id: "APPLICATION_CLIENT_ID"
                azure_tenant_id: "APPLICATION_DIRECTORY_TENANT_ID"
                azure_client_secret: "VALUE_OF_NEW_CLIENT_SECRET"
            sp:
                NameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
                assertionConsumerService:
                    binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                attributeConsumingService:
                    serviceName: "Psono"
                    serviceDescription: "Psono password manager"
                    requestedAttributes:
                        -
                            attributeValue: []
                            friendlyName: ""
                            isRequired: false
                            name: "username"
                            nameFormat: ""
                privateKey: "SP_PRIVATE_CERTIFICATE"
                singleLogoutService:
                    binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                x509cert: "SP_X509CERT"
                autoprovision_psono_folder: false
                autoprovision_psono_group: false
            strict: true
            security:
                requestedAuthnContext: false
    
    • Change serviceName to match the name of your Azure's custom application
    • Change USER_DOMAIN to match your domain.tld
    • Replace REPLACE_WITH_LOGIN_URL with the "Login Url" usually something like https://login.microsoftonline.com/...
    • Replace REPLACE_WITH_AZURE_AD_IDENTIFIER with the Microsoft Entra ID (Azure AD) identifier usually something like https://sts.windows.net/...
    • Replace CERT_FROM_AZURE_APPLICATION with the "Certificate (Base64)" from previous Azure configuration. (remove all line breaks)
    • Replace SP_PRIVATE_CERTIFICATE with the content of the previous generated "sp_private_key.key". (remove all line breaks)
    • Replace APPLICATION_CLIENT_ID with the "Application (client) ID"
    • Replace APPLICATION_DIRECTORY_TENANT_ID with the "Directory (tenant) ID"
    • Replace VALUE_OF_NEW_CLIENT_SECRET with the "Value" of the created client secret
    • Replace SP_X509CERT with the content of the previous generated "sp_x509cert.crt". (remove all line breaks)

    Restart the server afterward

  3. Adjust authentication methods

    Make sure that SAML is part of the AUTHENTICATION_METHODS parameter in your settings.yaml e.g.

    AUTHENTICATION_METHODS: ['SAML']
    

    Restart the server afterward

  4. (optional) Server Secrets

    By default the server will keep a copy of the user's secret keys to allow people to login without a password. If you want true client side encryption and as such force users to enter separate password for the encryption you specify the following in your settings.yaml. You can also decide later and change that and migrate users during the login or apply this setting only to particular users or groups with policies in the Admin Portal.

    COMPLIANCE_SERVER_SECRETS: 'noone'
    

    WARNING

    If a user loses his password he will lose all his data.

  5. (optional) Debug Mode

    It is helpful in the later debugging to enable debug mode.

    DEBUG: True
    

    WARNING

    Restart the server afterward and don't forget to remove it before going to production.

# Client (config.json)

Now you have to configure your client, so your users can use this configured IDP.

  1. Basic

    Update your config.json similar to the one shown below.

    {
      ...
        "authentication_methods": ["SAML"],
        "saml_provider": [{
          "title": "SAML Login",
          "provider_id": 1,
          "button_name": "Login "
        }]
      ...
    }
    

    The variable authentication_methods restricts the allowed login methods. In the example above only SAML will be allowed and the normal login "hidden". The title and button_name can be adjusted however you like. The provider_id needs to match the one that you used on your server.

  2. (optional) Automatic login

    You may want to "automatically" click on the login button to initiate the login flow. You can accomplish this by modifying the config.json as shown below:

    {
      ...
        "authentication_methods": ["SAML"],
        "auto_login": true,
      ...
    }
    

    WARNING

    This will only work if you have just one provider configured with only one authentication method. Users won't be able to modify the server url nor choose to register or interact with the login form in any other way.