# 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 in all Versions up to 10 SSO Applications. Also if you are using Office 365 it is included. (See: azure.microsoft.com/en-us/pricing/details/active-directory/ (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.
Enable Microsoft Entra ID (Azure AD) SSO
Go to your Microsoft Entra ID (Azure AD) Enterprise Applications (opens new window).
Create Application
Click on "New Application" and choose "Non-gallery application". Select a Name and click on "Add".
TIP
If you choose an other Name except 'Psono', you need to configure this in the settings.yaml
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 SAML on the Application
Click on "2. Set up single sign on" and then choose "SAML".
Configure the steps as shown in the picture below and save it. Copy the marked lines.
Configure the "User Attributes & Claims" section as shown below:
Configure group claim with "Add a group claim":
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.
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"
Select new application
Click on "All applications" and select the created application
Create new API Permission
In the left menu click on "API permissions" and then "Add a permission"
Select "Microsoft Graph"
Select "Application permissions"
Choose "Directory.Read.All"
Search for "Directory.Read.All", check it, and then click on "Add permission" at the bottom.
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" .
Create new client secret
On the left side click on "Certificates & secrets" and then "New client secret"
Enter a descriptive name and choose an expiration date.
Copy the "Value" of the new client secret. We will need it later and it won't be displayed again.
Go to "Overview"
Go to overview and take a copy of the "Application (client) ID" and the "Directory (tenant) ID"
# Server (settings.yaml)
During the installation of the server you have created a settings.yaml that needs to be adjusted now.
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).
Change or add SAML configuration in to settings.yaml. Comments inside the config:
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: "username" email_attribute: "email" 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
- Change
Adjust authentication methods
Make sure that
SAML
is part of theAUTHENTICATION_METHODS
parameter in your settings.yaml e.g.AUTHENTICATION_METHODS: ['SAML']
Restart the server afterward
(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.
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.(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.