Para mejorar la seguridad y la experiencia del usuario, F5 NGINX Plus (R29+) ahora tiene soporte para Security Assertion Markup Language (SAML). SAML, un protocolo bien establecido que proporciona inicio de sesión único (SSO) a aplicações web, permite que un proveedor de identidad (IdP) autentique a los usuarios para acceder a un recurso y luego pasa esa información a un proveedor de servicios (SP) para su autorización.
En esta publicación de blog, cubrimos paso a paso cómo integrar NGINX con Microsoft Entra ID , anteriormente conocido como Azure Active Directory (Azure AD), mediante una aplicação web que no admite SAML de forma nativa. También cubrimos cómo implementar SSO para la aplicação e integrarlo con el ecosistema de Microsoft Entra ID. Si sigue el tutorial, también aprenderá cómo NGINX puede extraer reclamos de una afirmación SAML (incluido UPN, nombre, apellido y membresías de grupo) y luego pasarlos a la aplicação a través de encabezados HTTP.
El tutorial incluye tres pasos:
Para completar este tutorial, necesitarás:
dev.sports.com.crt y dev.sports.com.key
)demonginx.cer
del IdPNota : Este tutorial no se aplica a las implementaciones de código abierto de NGINX porque el almacén de clave-valor es exclusivo de NGINX Plus.
En esta configuración, NGINX Plus actúa como un SP SAML y puede participar en una implementación de SSO con un IdP SAML, que se comunica indirectamente con NGINX Plus a través del agente de usuario.
El siguiente diagrama ilustra el flujo del proceso SSO, con iniciación de SP y enlaces POST para solicitud y respuesta. Es importante señalar nuevamente que este canal de comunicación no es directo y se gestiona a través del Agente de Usuario.
Figura 1: SSO iniciado por SAML SP con enlaces POST para AuthnRequest y Response
Para acceder a su portal de administración de ID de Microsoft Entra, inicie sesión y navegue al panel de la izquierda. Seleccione Microsoft Entra ID y luego haga clic en el título del directorio que requiere configuración de SSO. Una vez seleccionado, elija Aplicações empresariales .
Figura 2: Selección de aplicações empresariales en el portal de gestión
Para crear una aplicação, haga clic en el botón Nueva aplicação en la parte superior del portal. En este ejemplo, creamos una aplicação llamada demonginx .
Figura 3: Creación de una nueva aplicação en Microsoft Entra ID
Después de ser redirigido a la aplicação recién creada Descripción general , vaya a Primeros pasos a través del menú de la izquierda y haga clic en Inicio de sesión único en Administrar . Luego, seleccione SAML como método de inicio de sesión único .
Figura 4: Uso de la sección SSO para iniciar la configuración de SAML
Para configurar el inicio de sesión único (SSO) en su aplicação empresarial, debe registrar NGINX Plus como proveedor de servicios (SP) en Microsoft Entra ID. Para ello, haga clic en el icono de lápiz junto a Editar en la configuración básica de SAML , como se muestra en la Figura 5.
Agregue los siguientes valores y luego haga clic en Guardar :
El uso de certificados de verificación es opcional. Al habilitar esta configuración, se deben abordar dos opciones de configuración en NGINX:
$saml_sp_sign_authn
en verdadero . Esto le indica al SP que firme la AuthnRequest enviada al IdP.$saml_sp_signing_key
. Asegúrese de cargar el certificado de clave pública correspondiente a Microsoft Entra ID para la verificación de la firma.Nota : En esta demostración, se han modificado los atributos y las reclamaciones, y se agregan nuevos atributos SAML. Estos atributos SAML son enviados por el IdP. Asegúrese de que su configuración de NGINX esté configurada para recibir y procesar correctamente estos atributos. Puede verificar y ajustar la configuración relacionada en el repositorio de GitHub de NGINX .
Descargue el certificado IdP (sin procesar) de Microsoft Entra ID y guárdelo en su instancia NGINX Plus.
Figura 5: Descargar el certificado IdP (sin procesar) de Microsoft Entra ID
Figura 6: Agregar un nuevo usuario o grupo
En Microsoft Entra ID, puede otorgar acceso a las aplicações de su empresa habilitadas para SSO agregando o asignando usuarios y grupos.
En el menú de la izquierda, haga clic en Usuario y grupos y luego en el botón superior Agregar usuario/grupo .
Asegúrese de tener los certificados necesarios antes de configurar archivos en su NGINX Plus SP:
dev.sports.com.crt y dev.sports.com.key
)demonginx.cer
)Nota : Los certificados deben estar en formato SPKI.
Para comenzar este paso, descargue el certificado IdP de Microsoft Entra ID para la verificación de la firma. Luego, convierte el formato PEM al formato DER:
En caso de que desee verificar las afirmaciones de SAML SP, se recomienda utilizar claves públicas/privadas que sean diferentes de las utilizadas para la terminación TLS.
Extraiga el certificado de clave pública en formato SPKI:
Edite el archivo frontend.conf para actualizar estos elementos:
ssl_certificate
– Actualización para incluir la ruta del certificado TLS.ssl_certificate_key
– Actualización para incluir la ruta de la clave privada TLS.En la implementación de producción, puede utilizar diferentes destinos de back-end según los requisitos comerciales. En este ejemplo, el backend proporciona una respuesta personalizada:
Hemos modificado los atributos y las notificaciones en Microsoft Entra ID agregando nuevas notificaciones para el correo del usuario y el objectid . Estas actualizaciones le permiten ofrecer una respuesta más personalizada y adaptada a su aplicação, lo que se traduce en una mejor experiencia de usuario.
Figura 7: Atributos y notificaciones modificados en Microsoft Entra ID
El siguiente paso es configurar NGINX, que redirigirá el tráfico a la aplicação backend. En esta demostración, la aplicação SAML backend está disponible públicamente en https://dev.sports.com .
Edite su archivo 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
Para que los atributos saml_attrib_mail
y saml_attrib_objectid
se reflejen en las configuraciones de NGINX, actualice la parte del almacén de clave-valor de saml_sp_configuration.conf
de la siguiente manera:
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;
A continuación, configure el archivo de configuración de SSO SAML. Este archivo contiene las configuraciones principales para el SP y el IdP. Para personalizarlo según su configuración específica de SP e IdP, debe ajustar los múltiples bloques map{} incluidos en el archivo.
Esta tabla proporciona descripciones de las variables dentro de saml_sp_configuration.conf
:
Variable | Descripción |
---|---|
id de entidad saml_sp | La URL utilizada por los usuarios para acceder a la aplicação. |
saml_sp_acs_url | La URL utilizada por el proveedor de servicios para recibir y procesar la respuesta SAML, extraer la identidad del usuario y luego otorgar o denegar el acceso al recurso solicitado en función de la información proporcionada. |
autenticación de señal saml_sp | Especifica si la solicitud SAML del SP al IdP debe estar firmada o no. La firma se realiza utilizando la clave de firma SP y es necesario cargar el certificado asociado al IdP para verificar la firma. |
clave de firma saml_sp | La clave de firma que se utiliza para firmar la solicitud SAML del SP al IdP. Asegúrese de cargar el certificado asociado al IdP para verificar la firma. |
id_de_entidad_saml_idp | La identidad que se utiliza para definir el IdP. |
saml_idp_sso_url | El punto final del IdP al que el SP envía la solicitud de afirmación SAML para iniciar la solicitud de autenticación. |
certificado de verificación saml_idp | La certificación utilizada para verificar las afirmaciones SAML firmadas recibidas del IdP. El certificado lo proporciona el IdP y debe estar en formato SPKI. |
saml_sp_slo_url | El punto final del SP al que el IdP envía la solicitud de cierre de sesión SAML (al iniciar un proceso de cierre de sesión) o la respuesta de cierre de sesión (al confirmar el cierre de sesión). |
saml_sp_sign_slo | Especifica si el SAML de cierre de sesión debe ser firmado por el SP o no. |
saml_idp_slo_url | El punto final del IdP al que el SP envía LogoutRequest (al iniciar un proceso de cierre de sesión) o LogoutResponse (al confirmar el cierre de sesión). |
saml_sp_want_signed_slo | Especifica si el SP de SAML desea que la respuesta o solicitud de cierre de sesión de SAML del IdP esté firmada o no. |
El código siguiente muestra los valores editados solo para este caso de uso en saml_sp_configuration.conf.
Nota : Asegúrese de que las partes restantes del archivo de configuración aún aparezcan en el archivo (por ejemplo, los almacenes de clave-valor). Asegúrese también de ajustar correctamente las variables dentro del archivo saml_sp_configuration.conf
en función de su implementación.
# 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;
Se requieren dos partes para probar la configuración:
Después de configurar el SAML SP usando NGINX Plus y el IdP usando Microsoft Entra ID, es crucial validar el flujo SAML. Este proceso de validación garantiza que la autenticación del usuario a través del IdP sea exitosa y que se conceda el acceso a los recursos protegidos por SP.
Para verificar el flujo SAML iniciado por SP, abra su navegador preferido y escriba https://dev.sports.com en la barra de direcciones. Esto le dirigirá a la página de inicio de sesión de IdP.
Figura 8: La página de inicio de sesión del IdP
Ingrese las credenciales de un usuario que esté configurado en la página de inicio de sesión del IdP. El IdP autenticará al usuario al enviar.
Figura 9: Ingresar las credenciales del usuario configurado
Al establecer exitosamente una sesión, se le concederá al usuario acceso al recurso protegido solicitado previamente. Posteriormente dicho recurso se mostrará en el navegador del usuario.
Figura 10: La página de la aplicação cargada correctamente
Se puede obtener información valiosa sobre el flujo SAML verificando los registros de SP e IdP. En el lado SP (NGINX Plus), asegúrese de que las cookies auth_token estén configuradas correctamente. En el lado del IdP (ID de Microsoft Entra), asegúrese de que el proceso de autenticación se complete sin errores y que la afirmación SAML se envíe al SP.
El archivo access.log
de NGINX debería verse así:
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" "-
El archivo debug.log
de NGINX se ve así:
2023/08/14 21:25:49 [info] 27513#27513: *399 js: SAML SP success, creating session _d4db9b93c415ee7b4e057a4bb195df6cd0be7e4d
El cierre de sesión único (SLO) de SAML permite a los usuarios cerrar la sesión de todos los IdP y SP involucrados con una sola acción. NGINX Plus admite escenarios de cierre de sesión iniciados por SP y por IdP, lo que mejora la seguridad y la experiencia del usuario en entornos SSO. En este ejemplo, utilizamos un escenario de cierre de sesión iniciado por SP.
Figura 11: SLO iniciado por SAML SP con enlaces POST/redireccionamiento para LogoutRequest y LogoutResponse
Después de autenticar su sesión, cierre la sesión accediendo a la URL de cierre de sesión configurada en su SP. Por ejemplo, si ha configurado https://dev.sports.com/logout como la URL de cierre de sesión en NGINX Plus, ingrese esa URL en la barra de direcciones de su navegador.
Figura 12: Cerrar sesión exitosamente
Para garantizar un cierre de sesión seguro, el SP debe iniciar una solicitud SAML que luego es verificada y procesada por el IdP. Esta acción finaliza efectivamente la sesión del usuario y el IdP enviará una respuesta SAML para redirigir el navegador del usuario nuevamente al SP.
¡Enhorabuena! NGINX Plus ahora puede funcionar como un SP SAML, brindando otra capa de seguridad y conveniencia al proceso de autenticación. Esta nueva capacidad es un importante paso adelante para NGINX Plus, convirtiéndola en una solución más sólida y versátil para las organizaciones que priorizan la seguridad y la eficiencia.
Puede comenzar a utilizar SAML con NGINX Plus hoy mismo iniciando una prueba gratuita de 30 días de NGINX Plus . Esperamos que le resulte útil y agradecemos sus comentarios.
Más información sobre NGINX Plus con SAML está disponible en los recursos a continuación.
"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.