Pour renforcer la sécurité et améliorer votre expérience, F5 NGINX Plus (R29+) supporte désormais le Security Assertion Markup Language (SAML). Ce protocole reconnu offre une authentification unique (SSO) aux applications web en permettant à un fournisseur d’identité (IdP) de valider votre identité pour accéder à une ressource, puis de transmettre ces informations à un fournisseur de services (SP) pour contrôle d’autorisation.
Dans cet article de blog, nous expliquons étape par étape comment intégrer NGINX à Microsoft Entra ID , anciennement connu sous le nom d’Azure Active Directory (Azure AD), à l’aide d’une application Web qui ne prend pas en charge nativement SAML. Nous expliquons également comment implémenter SSO pour l'application et l'intégrer à l'écosystème Microsoft Entra ID. En suivant le didacticiel, vous apprendrez également comment NGINX peut extraire des revendications d'une assertion SAML (y compris le nom d'utilisateur principal, le prénom, le nom et les appartenances aux groupes), puis les transmettre à l'application via des en-têtes HTTP.
Le tutoriel comprend trois étapes :
Pour réaliser ce tutoriel, vous avez besoin de :
dev.sports.com.crt et dev.sports.com.key
)demonginx.cer
depuis l'IdPNote : Ce didacticiel ne s'applique pas aux déploiements NGINX Open Source car le magasin clé-valeur est exclusif à NGINX Plus.
Dans cette configuration, NGINX Plus agit comme un SP SAML et peut participer à une implémentation SSO avec un IdP SAML, qui communique indirectement avec NGINX Plus via l'agent utilisateur.
Le diagramme ci-dessous illustre le flux du processus SSO, avec l'initiation SP et les liaisons POST pour la demande et la réponse. Il est essentiel de noter à nouveau que ce canal de communication n’est pas direct et est géré via l’agent utilisateur.
Figure 1 : SSO initié par SAML SP avec liaisons POST pour AuthnRequest et Response
Pour accéder à votre portail de gestion Microsoft Entra ID, connectez-vous et accédez au panneau de gauche. Sélectionnez Microsoft Entra ID , puis cliquez sur le titre du répertoire qui nécessite une configuration SSO. Une fois sélectionné, choisissez Applications d'entreprise .
Figure 2 : Choix des applications d'entreprise dans le portail de gestion
Pour créer une application, cliquez sur le bouton Nouvelle application en haut du portail. Dans cet exemple, nous avons créé une application appelée demonginx .
Figure 3 : Créer une nouvelle application dans Microsoft Entra ID
Après avoir été redirigé vers l' aperçu de l'application nouvellement créée, accédez à Mise en route via le menu de gauche et cliquez sur Authentification unique sous Gérer . Ensuite, sélectionnez SAML comme méthode d’authentification unique .
Figure 4 : Utilisation de la section SSO pour démarrer la configuration SAML
Pour configurer l'authentification unique dans votre application d'entreprise, vous devez enregistrer NGINX Plus en tant que fournisseur de services dans Microsoft Entra ID. Pour ce faire, cliquez sur l'icône en forme de crayon en regard de Modifier dans la configuration SAML de base , comme illustré à la Figure 5.
Ajoutez les valeurs suivantes puis cliquez sur Enregistrer :
L'utilisation de certificats de vérification est facultative. Lors de l'activation de ce paramètre, deux options de configuration dans NGINX doivent être traitées :
$saml_sp_sign_authn
sur true . Cela demande au SP de signer l'AuthnRequest envoyée à l'IdP.$saml_sp_signing_key
. Assurez-vous de télécharger le certificat de clé publique correspondant sur Microsoft Entra ID pour la vérification de la signature.Note : Dans cette démo, les attributs et les revendications ont été modifiés et de nouveaux attributs SAML ont été ajoutés. Ces attributs SAML sont envoyés par l'IdP. Assurez-vous que votre configuration NGINX est configurée pour recevoir et traiter correctement ces attributs. Vous pouvez vérifier et ajuster les paramètres associés dans le référentiel GitHub NGINX .
Téléchargez le certificat IdP (brut) depuis Microsoft Entra ID et enregistrez-le sur votre instance NGINX Plus.
Figure 5 : Téléchargement du certificat IdP (brut) depuis Microsoft Entra ID
Figure 6 : Ajouter un nouvel utilisateur ou groupe
Dans Microsoft Entra ID, vous pouvez accorder l’accès à vos applications d’entreprise compatibles SSO en ajoutant ou en attribuant des utilisateurs et des groupes.
Dans le menu de gauche, cliquez sur Utilisateurs et groupes puis sur le bouton supérieur Ajouter un utilisateur/groupe .
Assurez-vous de disposer des certificats nécessaires avant de configurer les fichiers dans votre SP NGINX Plus :
dev.sports.com.crt et dev.sports.com.key
)demonginx.cer
)Note : Les certificats doivent être au format SPKI.
Pour commencer cette étape, téléchargez le certificat IdP depuis Microsoft Entra ID pour la vérification de la signature. Ensuite, convertissez le format PEM au format DER :
Si vous souhaitez vérifier les assertions SAML SP, il est recommandé d’utiliser des clés publiques/privées différentes de celles utilisées pour la terminaison TLS.
Extraire le certificat de clé publique au format SPKI :
Modifiez le fichier frontend.conf pour mettre à jour ces éléments :
ssl_certificate
– Mise à jour pour inclure le chemin du certificat TLS.ssl_certificate_key
– Mise à jour pour inclure le chemin de la clé privée TLS.Dans le déploiement de production, vous pouvez utiliser différentes destinations back-end en fonction des besoins de l'entreprise. Dans cet exemple, le backend fournit une réponse personnalisée :
Nous avons modifié les attributs et les revendications dans Microsoft Entra ID en ajoutant de nouvelles revendications pour le courrier électronique et l'ID d'objet de l'utilisateur. Ces mises à jour vous permettent de fournir une réponse plus personnalisée et adaptée à votre application, ce qui se traduit par une expérience utilisateur améliorée.
Figure 7 : Attributs et revendications modifiés dans Microsoft Entra ID
L’étape suivante consiste à configurer NGINX, qui dirigera le trafic vers l’application backend. Dans cette démo, l'application SAML backend est disponible publiquement sur https://dev.sports.com .
Modifiez votre fichier frontend.conf
:
# This is file frontend.conf
# This is the backend application we are protecting with SAML SSO
upstream my_backend {
zone my_backend 64k;
server dev.sports.com;
}
# Custom log format to include the 'NameID' subject in the REMOTE_USER field
log_format saml_sso '$remote_addr - $saml_name_id [$time_local] "$request" "$host" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# The frontend server - reverse proxy with SAML SSO authentication
#
server {
# Functional locations implementing SAML SSO support
include conf.d/saml_sp.server_conf;
# Reduce severity level as required
error_log /var/log/nginx/error.log debug;
listen 443 ssl;
ssl_certificate /home/ubuntu/dev.sports.com.crt;
ssl_certificate_key /home/ubuntu/dev.sports.com.key;
ssl_session_cache shared:SSL:5m;
location / {
# When a user is not authenticated (i.e., the "saml_access_granted."
# variable is not set to "1"), an HTTP 401 Unauthorized error is
# returned, which is handled by the @do_samlsp_flow named location.
error_page 401 = @do_samlsp_flow;
if ($saml_access_granted != "1") {
return 401;
}
# Successfully authenticated users are proxied to the backend,
# with the NameID attribute passed as an HTTP header
proxy_set_header mail $saml_attrib_mail; # Microsoft Entra ID's user.mail
proxy_set_header objectid $saml_attrib_objectid; # Microsoft Entra ID's objectid
access_log /var/log/nginx/access.log saml_sso;
proxy_pass http://my_backend;
proxy_set_header Host dev.sports.com;
return 200 "Welcome to Application page\n My objectid is $http_objectid\n My email is $http_mail\n";
default_type text/plain;
}
}
# vim: syntax=nginx
Pour que les attributs saml_attrib_mail
et saml_attrib_objectid
soient reflétés dans les configurations NGINX, mettez à jour la partie clé-valeur du fichier saml_sp_configuration.conf
comme suit :
keyval_zone zone=saml_attrib_mail:1M state=/var/lib/nginx/state/saml_attrib_email.json timeout=1h;
keyval $cookie_auth_token $saml_attrib_mail zone=saml_attrib_mail;
keyval_zone zone=saml_attrib_objectid:1M state=/var/lib/nginx/state/saml_attrib_objectid.json timeout=1h;
keyval $cookie_auth_token $saml_attrib_objectid zone=saml_attrib_objectid;
Ensuite, configurez le fichier de configuration SAML SSO. Ce fichier contient les configurations principales du SP et de l'IdP. Pour le personnaliser en fonction de votre configuration SP et IdP spécifique, vous devez ajuster les multiples blocs map{} inclus dans le fichier.
Ce tableau fournit des descriptions des variables dans saml_sp_configuration.conf
:
Variable | Description |
---|---|
saml_sp_entity_id | L'URL utilisée par les utilisateurs pour accéder à l'application. |
saml_sp_acs_url | Le fournisseur de services utilise cette URL pour recevoir et traiter la réponse SAML, extraire votre identité, puis vous accorder ou refuser l’accès à la ressource demandée selon les informations fournies. |
saml_sp_sign_authn | Spécifie si la demande SAML du SP à l'IdP doit être signée ou non. La signature est effectuée à l'aide de la clé de signature SP et vous devez télécharger le certificat associé sur l'IdP pour vérifier la signature. |
Clé de signature saml_sp | La clé de signature utilisée pour signer la demande SAML du SP à l'IdP. Assurez-vous de télécharger le certificat associé sur l'IdP pour vérifier la signature. |
ID d'entité saml_idp | L'identité utilisée pour définir l'IdP. |
saml_idp_sso_url | Le point de terminaison IdP auquel le SP envoie la demande d’assertion SAML pour lancer la demande d’authentification. |
certificat_de_vérification_idp_saml | La certification utilisée pour vérifier les assertions SAML signées reçues de l'IdP. Le certificat est fourni par l'IdP et doit être au format SPKI. |
saml_sp_slo_url | Le point de terminaison SP auquel l'IdP envoie la demande de déconnexion SAML (lors du lancement d'un processus de déconnexion) ou la réponse de déconnexion (lors de la confirmation de la déconnexion). |
saml_sp_sign_slo | Spécifie si le SAML de déconnexion doit être signé par le SP ou non. |
saml_idp_slo_url | Le point de terminaison IdP auquel le SP envoie la LogoutRequest (lors du lancement d'un processus de déconnexion) ou la LogoutResponse (lors de la confirmation de la déconnexion). |
saml_sp_veut_signer_slo | Spécifie si le SP SAML souhaite que la réponse ou la demande de déconnexion SAML de l'IdP soit signée ou non. |
Le code ci-dessous affiche les valeurs modifiées uniquement pour ce cas d'utilisation dans saml_sp_configuration.conf.
Note : Assurez-vous que les parties restantes du fichier de configuration apparaissent toujours dans le fichier (par exemple, les magasins de clés-valeurs). Assurez-vous également d’ajuster correctement les variables dans le fichier saml_sp_configuration.conf
en fonction de votre déploiement.
# SAML SSO configuration
map $host $saml_sp_entity_id {
# Unique identifier that identifies the SP to the IdP.
# Must be URL or URN.
default "https://dev.sports.com";
}
map $host $saml_sp_acs_url {
# The ACS URL, an endpoint on the SP where the IdP
# will redirect to with its authentication response.
# Must match the ACS location defined in the "saml_sp.serer_conf" file.
default "https://dev.sports.com/saml/acs";
}
map $host $saml_sp_request_binding {
# Refers to the method by which an authentication request is sent from
# the SP to an IdP during the Single Sign-On (SSO) process.
# Only HTTP-POST or HTTP-Redirect methods are allowed.
default 'HTTP-POST';
}
map $host $saml_sp_sign_authn {
# Whether the SP should sign the AuthnRequest sent to the IdP.
default "false";
}
map $host $saml_sp_decryption_key {
# Specifies the private key that the SP uses to decrypt encrypted assertion
# or NameID from the IdP.
default "";
}
map $host $saml_sp_force_authn {
# Whether the SP should force re-authentication of the user by the IdP.
default "false";
}
map $host $saml_sp_nameid_format {
# Indicates the desired format of the name identifier in the SAML assertion
# generated by the IdP. Check section 8.3 of the SAML 2.0 Core specification
# (http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf)
# for the list of allowed NameID Formats.
default "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified";
}
map $host $saml_sp_relay_state {
# Relative or absolute URL the SP should redirect to
# after successful sign on.
default "";
}
map $host $saml_sp_want_signed_response {
# Whether the SP wants the SAML Response from the IdP
# to be digitally signed.
default "false";
}
map $host $saml_sp_want_signed_assertion {
# Whether the SP wants the SAML Assertion from the IdP
# to be digitally signed.
default "true";
}
map $host $saml_sp_want_encrypted_assertion {
# Whether the SP wants the SAML Assertion from the IdP
# to be encrypted.
default "false";
}
map $host $saml_idp_entity_id {
# Unique identifier that identifies the IdP to the SP.
# Must be URL or URN.
default "https://sts.windows.net/8807dced-9637-4205-a520-423077750c60/";
}
map $host $saml_idp_sso_url {
# IdP endpoint that the SP will send the SAML AuthnRequest to initiate
# an authentication process.
default "https://login.microsoftonline.com/8807dced-9637-4205-a520-423077750c60/saml2";
}
map $host $saml_idp_verification_certificate {
# Certificate file that will be used to verify the digital signature
# on the SAML Response, LogoutRequest or LogoutResponse received from IdP.
# Must be public key in PKCS#1 format. See documentation on how to convert
# X.509 PEM to DER format.
default "/etc/nginx/conf.d/demonginx.spki";
}
######### Single Logout (SLO) #########
map $host $saml_sp_slo_url {
# SP endpoint that the IdP will send the SAML LogoutRequest to initiate
# a logout process or LogoutResponse to confirm the logout.
default "https://dev.sports.com/saml/sls";
}
map $host $saml_sp_slo_binding {
# Refers to the method by which a LogoutRequest or LogoutResponse
# is sent from the SP to an IdP during the Single Logout (SLO) process.
# Only HTTP-POST or HTTP-Redirect methods are allowed.
default 'HTTP-POST';
}
map $host $saml_sp_sign_slo {
# Whether the SP must sign the LogoutRequest or LogoutResponse
# sent to the IdP.
default "false";
}
map $host $saml_idp_slo_url {
# IdP endpoint that the SP will send the LogoutRequest to initiate
# a logout process or LogoutResponse to confirm the logout.
# If not set, the SAML Single Logout (SLO) feature is DISABLED and
# requests to the 'logout' location will result in the termination
# of the user session and a redirect to the logout landing page.
default "https://login.microsoftonline.com/8807dced-9637-4205-a520-423077750c60/saml2";
}
map $host $saml_sp_want_signed_slo {
# Whether the SP wants the SAML LogoutRequest or LogoutResponse from the IdP
# to be digitally signed.
default "true";
}
map $host $saml_logout_landing_page {
# Where to redirect user after requesting /logout location. This can be
# replaced with a custom logout page, or complete URL.
default "/_logout"; # Built-in, simple logout page
}
map $proto $saml_cookie_flags {
http "Path=/; SameSite=lax;"; # For HTTP/plaintext testing
https "Path=/; SameSite=lax; HttpOnly; Secure;"; # Production recommendation
}
map $http_x_forwarded_port $redirect_base {
"" $proto://$host:$server_port;
default $proto://$host:$http_x_forwarded_port;
}
map $http_x_forwarded_proto $proto {
"" $scheme;
default $http_x_forwarded_proto;
}
# ADVANCED CONFIGURATION BELOW THIS LINE
# Additional advanced configuration (server context) in saml_sp.server_conf
######### Shared memory zones that keep the SAML-related key-value databases
# Zone for storing AuthnRequest and LogoutRequest message identifiers (ID)
# to prevent replay attacks. (REQUIRED)
# Timeout determines how long the SP waits for a response from the IDP,
# i.e. how long the user authentication process can take.
keyval_zone zone=saml_request_id:1M state=/var/lib/nginx/state/saml_request_id.json timeout=5m;
# Zone for storing SAML Response message identifiers (ID) to prevent replay attacks. (REQUIRED)
# Timeout determines how long the SP keeps IDs to prevent reuse.
keyval_zone zone=saml_response_id:1M state=/var/lib/nginx/state/saml_response_id.json timeout=1h;
# Zone for storing SAML session access information. (REQUIRED)
# Timeout determines how long the SP keeps session access decision (the session lifetime).
keyval_zone zone=saml_session_access:1M state=/var/lib/nginx/state/saml_session_access.json timeout=1h;
# Zone for storing SAML NameID values. (REQUIRED)
# Timeout determines how long the SP keeps NameID values. Must be equal to session lifetime.
keyval_zone zone=saml_name_id:1M state=/var/lib/nginx/state/saml_name_id.json timeout=1h;
# Zone for storing SAML NameID format values. (REQUIRED)
# Timeout determines how long the SP keeps NameID format values. Must be equal to session lifetime.
keyval_zone zone=saml_name_id_format:1M state=/var/lib/nginx/state/saml_name_id_format.json timeout=1h;
# Zone for storing SAML SessionIndex values. (REQUIRED)
# Timeout determines how long the SP keeps SessionIndex values. Must be equal to session lifetime.
keyval_zone zone=saml_session_index:1M state=/var/lib/nginx/state/saml_session_index.json timeout=1h;
# Zone for storing SAML AuthnContextClassRef values. (REQUIRED)
# Timeout determines how long the SP keeps AuthnContextClassRef values. Must be equal to session lifetime.
keyval_zone zone=saml_authn_context_class_ref:1M state=/var/lib/nginx/state/saml_authn_context_class_ref.json timeout=1h;
# Zones for storing SAML attributes values. (OPTIONAL)
# Timeout determines how long the SP keeps attributes values. Must be equal to session lifetime.
keyval_zone zone=saml_attrib_uid:1M state=/var/lib/nginx/state/saml_attrib_uid.json timeout=1h;
keyval_zone zone=saml_attrib_name:1M state=/var/lib/nginx/state/saml_attrib_name.json timeout=1h;
keyval_zone zone=saml_attrib_memberOf:1M state=/var/lib/nginx/state/saml_attrib_memberOf.json timeout=1h;
######### SAML-related variables whose value is looked up by the key (session cookie) in the key-value database.
# Required:
keyval $saml_request_id $saml_request_redeemed zone=saml_request_id; # SAML Request ID
keyval $saml_response_id $saml_response_redeemed zone=saml_response_id; # SAML Response ID
keyval $cookie_auth_token $saml_access_granted zone=saml_session_access; # SAML Access decision
keyval $cookie_auth_token $saml_name_id zone=saml_name_id; # SAML NameID
keyval $cookie_auth_token $saml_name_id_format zone=saml_name_id_format; # SAML NameIDFormat
keyval $cookie_auth_token $saml_session_index zone=saml_session_index; # SAML SessionIndex
keyval $cookie_auth_token $saml_authn_context_class_ref zone=saml_authn_context_class_ref; # SAML AuthnContextClassRef
# Optional:
keyval $cookie_auth_token $saml_attrib_uid zone=saml_attrib_uid;
keyval $cookie_auth_token $saml_attrib_name zone=saml_attrib_name;
keyval $cookie_auth_token $saml_attrib_memberOf zone=saml_attrib_memberOf;
keyval_zone zone=saml_attrib_mail:1M state=/var/lib/nginx/state/saml_attrib_mail.json timeout=1h;
keyval $cookie_auth_token $saml_attrib_mail zone=saml_attrib_mail;
keyval $cookie_auth_token $saml_attrib_objectid zone=saml_attrib_objectid;
keyval_zone zone=saml_attrib_objectid:1M state=/var/lib/nginx/state/saml_attrib_objectid.json timeout=1h;
######### Imports a module that implements SAML SSO and SLO functionality
js_import samlsp from conf.d/saml_sp.js;
Deux parties sont nécessaires pour tester la configuration :
Après avoir configuré le fournisseur de services SAML avec NGINX Plus et l’IdP avec Microsoft Entra ID, vous devez impérativement valider le flux SAML. Cette validation confirme que l’authentification de l’utilisateur via l’IdP réussit et que vous pouvez accéder aux ressources protégées par le fournisseur de services.
Pour vérifier le flux SAML initié par SP, ouvrez votre navigateur préféré et saisissez https://dev.sports.com dans la barre d'adresse. Cela vous dirige vers la page de connexion IdP.
Figure 8 : La page de connexion IdP
Saisissez les informations d’identification d’un utilisateur configuré dans la page de connexion de l’IdP. L'IdP authentifiera l'utilisateur lors de la soumission.
Figure 9 : Saisie des identifiants de l’utilisateur configuré
Nous vous accorderons l'accès à la ressource protégée demandée dès l'établissement réussi de la session. Ensuite, votre navigateur affichera cette ressource.
Figure 10 : La page de l'application chargée avec succès
Des informations précieuses sur le flux SAML peuvent être obtenues en vérifiant les journaux SP et IdP. Du côté SP (NGINX Plus), assurez-vous que les cookies auth_token sont correctement définis. Du côté IdP (Microsoft Entra ID), assurez-vous que le processus d’authentification se termine sans erreur et que l’assertion SAML est envoyée au SP.
Le journal d'accès
NGINX devrait ressembler à ceci :
127.0.0.1 - - [14/Aug/2023:21:25:49 +0000] "GET / HTTP/1.0" 200 127 "https://login.microsoftonline.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15" "-"
99.187.244.63 - Akash Ananthanarayanan [14/Aug/2023:21:25:49 +0000] "GET / HTTP/1.1" "dev.sports.com" 200 127 "https://login.microsoftonline.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15" "-
Alors que le fichier de débogage
NGINX ressemble à ceci :
2023/08/14 21:25:49 [info] 27513#27513: *399 js: SAML SP success, creating session _d4db9b93c415ee7b4e057a4bb195df6cd0be7e4d
SAML Single Logout (SLO) permet aux utilisateurs de se déconnecter de tous les IdP et SP impliqués en une seule action. NGINX Plus prend en charge les scénarios de déconnexion initiés par le SP et l'IdP, améliorant ainsi la sécurité et l'expérience utilisateur dans les environnements SSO. Dans cet exemple, nous utilisons un scénario de déconnexion initié par SP.
Figure 11 : SLO initié par le SP SAML avec liaisons POST/redirection pour LogoutRequest et LogoutResponse
Après avoir authentifié votre session, déconnectez-vous en accédant à l'URL de déconnexion configurée dans votre SP. Par exemple, si vous avez configuré https://dev.sports.com/logout comme URL de déconnexion dans NGINX Plus, saisissez cette URL dans la barre d'adresse de votre navigateur.
Figure 12 : Déconnexion réussie de la session
Pour garantir une déconnexion sécurisée, le SP doit lancer une requête SAML qui est ensuite vérifiée et traitée par l'IdP. Cette action met effectivement fin à la session de l’utilisateur, et l’IdP enverra alors une réponse SAML pour rediriger le navigateur de l’utilisateur vers le SP.
Félicitations ! NGINX Plus peut désormais servir de SP SAML, offrant une autre couche de sécurité et de commodité au processus d'authentification. Cette nouvelle fonctionnalité constitue une avancée significative pour NGINX Plus, ce qui en fait une solution plus robuste et polyvalente pour les organisations privilégiant la sécurité et l’efficacité.
Vous pouvez commencer à utiliser SAML avec NGINX Plus dès aujourd'hui en démarrant un essai gratuit de 30 jours de NGINX Plus . Nous espérons que vous le trouverez utile et serons ravis de recevoir vos commentaires.
Vous trouverez plus d’informations sur NGINX Plus avec SAML dans les ressources ci-dessous.
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."