Saltar al contenido

Diagrama de flujo SAML SSO: inicio de sesión iniciado por el SP y por el IdP

Cómo funciona el inicio de sesión único con SAML 2.0: flujos iniciados por el SP y por el IdP, qué contiene una respuesta SAML, qué debe comprobar tu app y dónde falla.

· Fundador y desarrollador

Publicado el

Diagrama de secuencia: usuario, navegador, proveedor de servicios y proveedor de identidad. La app redirige al IdP con un AuthnRequest; un fragmento opcional muestra login y MFA; el IdP devuelve un formulario que envía la SAMLResponse a la URL ACS; la app la valida y fija una cookie.

El primer cliente grande que firme un contrato pedirá inicio de sesión único con su proveedor de identidad, y muy a menudo eso significa SAML 2.0. El estándar es de 2005, mueve XML mediante redirecciones del navegador y envíos de formularios, y sus mensajes de error van de lo vago a lo mudo. La mayoría de los bugs de SAML, incluidos agujeros de seguridad graves, vienen de no saber exactamente qué mensaje va adónde y qué debe comprobar el proveedor de servicios.

Este artículo recorre el flujo iniciado por el SP mensaje a mensaje con un diagrama de secuencia, y después la variante iniciada por el IdP y sus riesgos, la anatomía de una respuesta SAML, la lista de comprobaciones para tu app, los metadatos y la rotación de certificados, y cómo se compara SAML con OpenID Connect.

Las tres partes

Parte En términos de SAML Ejemplos
El navegador del usuario Agente de usuario Cualquier navegador
Tu aplicación Proveedor de servicios (SP) Tu app SaaS
El sistema de inicio de sesión del cliente Proveedor de identidad (IdP) Microsoft Entra ID, Okta, Google Workspace, AD FS

En el perfil habitual Web Browser SSO, el SP y el IdP nunca hablan directamente entre sí. Cada mensaje viaja a través del navegador, como una redirección o un formulario que se envía solo. Lo que comparten es configuración, intercambiada una vez como metadatos: el entity ID de cada lado, la URL de inicio de sesión del IdP, la URL del Assertion Consumer Service (ACS) del SP y el certificado de firma del IdP.

El flujo iniciado por el SP, paso a paso

El usuario empieza en tu app:

  1. El usuario abre https://app.example.com/dashboard sin sesión.
  2. Tu app crea un AuthnRequest con un ID único, su entity ID y su URL ACS, guarda el ID en el estado del inicio de sesión pendiente y redirige el navegador al IdP. Con el binding HTTP-Redirect, la solicitud viaja en la query string como SAMLRequest (comprimida con deflate y codificada en base64), junto a un valor RelayState que recuerda adónde quería ir el usuario.
  3. El IdP autentica al usuario: contraseña y MFA, o una sesión del IdP ya existente, en cuyo caso el usuario no ve nada.
  4. El IdP devuelve una página HTML con un formulario que envía por POST una SAMLResponse firmada y el mismo RelayState a tu URL ACS. Es el binding HTTP-POST, y un pequeño script envía el formulario automáticamente.
  5. Tu app valida la respuesta, crea su propia cookie de sesión y redirige al usuario a la página guardada en RelayState.

A partir de ahí, la sesión propia de tu app decide quién es el usuario. SAML solo vuelve a intervenir cuando esa sesión caduca.

La especificación de bindings limita RelayState a 80 bytes, así que guarda la URL de retorno real en el servidor y envía una clave corta.

Qué contiene una respuesta SAML

Recortada a las partes que lee tu app, una respuesta tiene este aspecto:

<samlp:Response ID="_r81c" InResponseTo="_req42" Destination="https://app.example.com/saml/acs">
  <saml:Assertion ID="_a77e">
    <saml:Issuer>https://idp.customer.com/entity</saml:Issuer>
    <ds:Signature>…</ds:Signature>
    <saml:Subject>
      <saml:NameID>ana@customer.com</saml:NameID>
      <saml:SubjectConfirmationData InResponseTo="_req42"
        Recipient="https://app.example.com/saml/acs" NotOnOrAfter="2026-11-02T09:05:00Z"/>
    </saml:Subject>
    <saml:Conditions NotBefore="2026-11-02T08:59:30Z" NotOnOrAfter="2026-11-02T09:05:00Z">
      <saml:AudienceRestriction><saml:Audience>https://app.example.com</saml:Audience></saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AttributeStatement>…email, name, groups…</saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>

La aserción es la declaración firmada: quién es el usuario (NameID), quién lo afirma (Issuer), para quién (Audience), durante cuánto tiempo y en respuesta a qué solicitud (InResponseTo).

La lista de comprobaciones

Tu endpoint ACS es donde la seguridad de SAML funciona o falla. Debe:

  1. Verificar la firma con el certificado de los metadatos del IdP, nunca con un certificado incrustado en el propio mensaje.
  2. Leer solo lo que cubre la firma. Los ataques de XML signature wrapping insertan una segunda aserción sin firmar y esperan que el código verifique un elemento y lea otro. Unos investigadores encontraron este fallo en 11 de 14 frameworks SAML importantes en 2012, y sigue volviendo: ruby-saml corrigió en 2024 una omisión de firma con CVSS 10.0 (CVE-2024-45409) y en 2025 dos omisiones por diferencias entre parsers (CVE-2025-25291 y CVE-2025-25292).
  3. Comprobar Issuer contra el entity ID del IdP de este cliente.
  4. Comprobar Audience contra tu propio entity ID.
  5. Comprobar Destination y Recipient contra tu URL ACS.
  6. Comprobar NotBefore y NotOnOrAfter con una tolerancia de uno o dos minutos por el desfase de reloj.
  7. Hacer coincidir InResponseTo con un ID de AuthnRequest que emitiste para este navegador y que aún no se ha usado.
  8. Rechazar las repeticiones recordando los ID de aserción hasta que caduquen.
  9. Tratar RelayState como no fiable. Redirige solo a rutas relativas o a una lista de permitidos, o tendrás una redirección abierta.

La lección de una década de vulnerabilidades en SAML: usa una biblioteca mantenida, fija su versión, aplica los parches rápido y nunca escribas tu propia verificación de firmas XML.

SSO iniciado por el IdP y por qué es más arriesgado

En el flujo iniciado por el IdP, el usuario empieza en el IdP, normalmente haciendo clic en el mosaico de tu app en un panel como el portal de Okta o Microsoft My Apps. El IdP envía por POST una respuesta no solicitada a tu URL ACS. No hubo AuthnRequest, así que no hay InResponseTo con el que hacer coincidir.

Iniciado por el SP Iniciado por el IdP
Empieza en Tu app El portal del IdP
AuthnRequest Sí No
Comprobación de InResponseTo Sí No es posible
Protección frente a CSRF de inicio de sesión Integrada Requiere cuidado adicional
Enlaces profundos Mediante RelayState Suele aterrizar en una página por defecto

Sin InResponseTo, un atacante que obtenga una respuesta válida, o que consiga que el navegador de una víctima envíe una, puede iniciar sesión a la víctima en la cuenta del atacante o repetir una respuesta robada dentro de su ventana de validez. Si los clientes necesitan mosaicos en el panel, el patrón más seguro es un mosaico que abra la URL de inicio de sesión de tu app, que a su vez inicia un flujo normal iniciado por el SP. Si tienes que aceptar respuestas no solicitadas, mantén una validez corta, exige ID de aserción de un solo uso y permítelo por cliente, no de forma global.

Metadatos, certificados y configuraciones multi-tenant

El IdP de cada cliente es una relación de confianza aparte. Guarda por tenant: el entity ID del IdP, la URL de inicio de sesión, los certificados de firma y el mapeo de atributos. El diagrama de arquitectura SaaS multi-tenant muestra dónde suele vivir esta configuración por tenant.

Los certificados de firma caducan, y un certificado caducado o rotado es la causa más común de que todo un cliente deje de poder iniciar sesión de repente. Acepta dos certificados por IdP durante un cambio, lee periódicamente la URL de metadatos del IdP si publica una y alerta semanas antes de la caducidad.

SAML autentica; no mantiene sincronizada tu lista de usuarios. Crear cuentas en el primer inicio de sesión es fácil, pero retirar el acceso cuando alguien se va requiere aprovisionamiento, normalmente SCIM 2.0 (RFC 7644). Sin él, un empleado desactivado conserva cualquier sesión que tu app ya haya emitido.

¿SAML u OpenID Connect?

SAML 2.0 OpenID Connect
Formato Aserciones XML con firmas XML JSON, con ID tokens JWT
Transporte Redirecciones del navegador y envíos de formularios Redirecciones más una solicitud de token por back-channel
Apps móviles y SPA Incómodo Diseñado para ellas
Uso típico SSO empresarial hacia apps SaaS Inicio de sesión de consumidores, APIs, SSO empresarial moderno

Las apps nuevas pueden empezar con OpenID Connect, pero los compradores empresariales seguirán pidiendo SAML, así que la mayoría de los productos B2B admiten ambos. El diagrama de flujo de OAuth 2.0 cubre el protocolo sobre el que se construye OpenID Connect.

El diagrama de SAML SSO

Diagrama de secuencia: usuario, navegador, proveedor de servicios y proveedor de identidad. La app redirige al IdP con un AuthnRequest; un fragmento opcional muestra login y MFA; el IdP devuelve un formulario que envía la SAMLResponse a la URL ACS; la app la valida y fija una cookie.

6 componentes · 11 conexiones

Abrir en Archboard
Contenido del diagrama
  • User
  • Browser
  • Service provider (your app)
  • Identity provider
  • no IdP session yet
  • 1. Open the app
  • 2. GET /dashboard (no session)
  • 3. 302 to IdP: SAMLRequest + RelayState
  • 4. GET /sso?SAMLRequest=…&RelayState=… (HTTP-Redirect)
  • 5. Login page
  • 6. Password + MFA
  • 7. HTML form: signed SAMLResponse + RelayState
  • 8. POST /saml/acs (HTTP-POST, auto-submit)
  • 9. 302 /dashboard + session cookie
  • 10. GET /dashboard (cookie)
  • 11. 200 OK
Inicio de sesión único SAML iniciado por el SP. La app redirige el navegador al proveedor de identidad con un AuthnRequest; el IdP autentica al usuario y envía por POST una respuesta firmada a la URL ACS de la app, que la valida antes de crear su propia sesión.

Cómo leerlo:

  • Cuatro participantes. El usuario, el navegador, tu app como proveedor de servicios y el proveedor de identidad. El tiempo avanza hacia abajo.
  • La redirección lleva el AuthnRequest y el RelayState de tu app al IdP, a través del navegador.
  • El fragmento opcional es el paso de inicio de sesión. Con una sesión del IdP ya existente, se omite y el usuario solo ve una redirección rápida.
  • El envío del formulario entrega la SAMLResponse firmada a la URL ACS. Tu app la valida y fija su propia cookie de sesión.
  • El bloque Markdown enumera las comprobaciones que debe hacer el endpoint ACS.

Dibujar flujos de SSO que ayuden a depurar

  • Dibuja el navegador como un participante propio. SAML es un protocolo de front-channel; ocultar el navegador oculta dónde se pueden interceptar o repetir los mensajes.
  • Indica el binding en cada flecha: redirección o POST, y el nombre del parámetro. La mayoría de los errores de configuración son una URL o un binding equivocados.
  • Pon los ID en los mensajes. Mostrar que InResponseTo repite el ID de la solicitud explica por qué se comprueba.
  • Dibuja el flujo iniciado por el IdP por separado, con su riesgo anotado, en lugar de como una rama del diagrama principal.

El ejemplo de diagrama de secuencia trata con más detalle los participantes, los fragmentos y las etiquetas, y el diagrama de arquitectura zero trust muestra dónde encaja el proveedor de identidad en un modelo de acceso más amplio.

Constrúyelo en Archboard

  1. Inicia sesión con Google o GitHub y crea un diagrama.
  2. Añade un Actor del pack Secuencia para el usuario y después tres nodos Línea de vida: Browser, Service provider e Identity provider.
  3. Dibuja los mensajes de arriba abajo como aristas entre las líneas de vida: la primera solicitud, la redirección con SAMLRequest y RelayState, la solicitud al IdP, el formulario con SAMLResponse, el POST a la URL ACS y la redirección final con la cookie de sesión.
  4. Añade un Fragmento combinado del pack Secuencia con el operador opt alrededor del paso de inicio de sesión y MFA.
  5. Añade un bloque Markdown del pack Básico con la lista de comprobaciones.

El ejemplo usa 6 nodos de diagrama, dentro del plan Free.

Preguntas frecuentes

¿Qué diferencia hay entre el SSO iniciado por el SP y el iniciado por el IdP? El inicio de sesión iniciado por el SP empieza en tu app, que envía un AuthnRequest al IdP. El iniciado por el IdP empieza en el portal del IdP, que envía por POST una respuesta no solicitada a tu app. El segundo no tiene ninguna solicitud con la que hacer coincidir la respuesta, lo que debilita la protección frente a repeticiones y CSRF de inicio de sesión.

¿Qué es una URL ACS? La URL del Assertion Consumer Service es el endpoint de tu app que recibe la respuesta SAML por HTTP POST. Se configura en el IdP y debe coincidir con los valores Destination y Recipient de cada respuesta.

¿Para qué se usa RelayState? Lleva el lugar al que el usuario quería llegar, para que tu app lo envíe allí después del inicio de sesión. Está limitado a 80 bytes y es una entrada no fiable, así que úsalo como clave de un estado guardado en el servidor o valídalo contra una lista de permitidos.

¿SAML está obsoleto? Es más antiguo que OpenID Connect y más difícil de implementar de forma segura, pero sigue siendo el estándar que esperan muchos proveedores de identidad y compradores empresariales. La mayoría de los productos B2B admiten ambos.

¿SAML elimina a los usuarios cuando dejan la empresa? No. SAML solo autentica al iniciar sesión. El desaprovisionamiento necesita SCIM u otra integración de aprovisionamiento, además de duraciones de sesión razonables en tu app.

Empieza gratis — un puesto, sin tarjeta de crédito.

Artículos relacionados

← Volver al blog

Abre un lienzo en un minuto

Inicia sesión con Google o GitHub. Gratis para un asiento. Mejora el plan cuando se una el equipo.