Seguridad e identidad
SAML 2.0 y single sign-on: aserciones, bindings y federación
Intermedio9 min de lecturaActualizado
Esta página se tradujo del inglés con ayuda de IA y se cotejó con el original. Leer la versión en inglés
SAML 2.0 sigue sosteniendo el inicio de sesión único en universidades, administraciones públicas y grandes empresas, e integrarse con él implica leer XML en lugar de JSON. Esta guía explica el modelo de federación, la anatomía de una aserción, los dos flujos de inicio y sus bindings, los metadatos y la rotación de certificados, los errores de firma que le dieron a SAML su mala fama y cuándo elegirlo frente a OpenID Connect.
Lo que aprenderás
- Explicar el modelo de federación y los roles de proveedor de identidad y proveedor de servicio
- Leer una aserción SAML e identificar el sujeto, las condiciones, las declaraciones y la firma
- Distinguir los flujos iniciados por el SP de los iniciados por el IdP, y los bindings Redirect y POST
- Intercambiar metadatos y rotar certificados de firma sin cortes de servicio
- Evitar los errores de validación de firma que permiten saltarse la autenticación
- Decidir entre SAML y OpenID Connect para una integración nueva
Mucho antes de que los navegadores hablaran JSON con los proveedores de identidad, las empresas necesitaban que un único inicio de sesión abriera una docena de aplicaciones, algunas de ellas funcionando en una organización completamente distinta. SAML 2.0, estandarizado por OASIS en 2005, lo resolvió con un vocabulario XML para formular y transportar declaraciones sobre un usuario autenticado, y desde entonces sostiene discretamente federaciones universitarias, portales de la administración y parques de aplicaciones corporativas. Si vendes software a grandes organizaciones, tarde o temprano un cliente te enviará un archivo de metadatos en lugar de un client secret.
Trabajar con SAML es distinto de trabajar con OpenID Connect en aspectos que van más allá del formato de serialización. La confianza se establece fuera de banda intercambiando certificados, no descargando un documento de discovery; la seguridad de todo el intercambio descansa en las firmas digitales XML, una especificación famosa por sus aristas; y no existe el concepto de access token para llamar a APIs. Esta guía cubre lo que necesitas para integrarte correctamente y lo que históricamente ha salido mal.
La federación y sus dos roles
Inicio de sesión único significa que un usuario se autentica una vez y las aplicaciones siguientes aceptan esa autenticación en lugar de volver a pedirla. La federación lo extiende más allá de los límites de una organización: la aplicación confía en una aserción emitida por un proveedor de identidad que no controla, en virtud de un certificado intercambiado de antemano.
- El proveedor de identidad (IdP) autentica al usuario y emite aserciones. Normalmente hay uno por organización.
- El proveedor de servicio (SP) es la aplicación que consume la aserción. Nunca ve las credenciales del usuario.
- La aserción es el documento XML firmado que contiene las declaraciones.
- El círculo de confianza es el conjunto de partes que han intercambiado metadatos y han acordado aceptar las declaraciones de las demás.
La consecuencia práctica es que las credenciales se quedan en el directorio del empleador. Cuando una persona deja la organización, se la desactiva una sola vez, de forma centralizada, y todas las aplicaciones federadas dejan de admitirla: es el argumento del ciclo de vida de la identidad que se desarrolla en gestión de identidades y accesos.
Anatomía de una aserción
Una aserción es un elemento <saml:Assertion> con un emisor, una firma, un sujeto, condiciones de validez y una o más declaraciones. Sin el ruido de los espacios de nombres, una aserción realista tiene este aspecto.
<saml:Assertion ID="_a1b2c3d4e5" IssueInstant="2026-09-07T09:14:22Z" Version="2.0"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Issuer>https://idp.university.example/idp/shibboleth</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> ... </ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
c7f1e0a9-2b44-4d7e-9f30-8a0e1c2b3d45
</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2026-09-07T09:19:22Z"
Recipient="https://app.example.com/saml/acs"
InResponseTo="_req-88f21a"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2026-09-07T09:14:12Z" NotOnOrAfter="2026-09-07T09:24:22Z">
<saml:AudienceRestriction>
<saml:Audience>https://app.example.com/saml/metadata</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2026-09-07T09:14:20Z" SessionIndex="_sess-4471">
<saml:AuthnContext>
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorContract
</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="urn:oid:0.9.2342.19200300.100.1.3">
<saml:AttributeValue>[email protected]</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1">
<saml:AttributeValue>staff</saml:AttributeValue>
<saml:AttributeValue>member</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
Cada parte impone obligaciones al consumidor. El formato del NameID determina si recibes un identificador reutilizable: persistent da un seudónimo estable y exclusivo de esta relación con el SP, transient da un valor válido solo durante una sesión y emailAddress da algo legible pero que puede cambiar. Las condiciones deben aplicarse: la restricción de audiencia es lo que impide que una aserción emitida para una aplicación se reutilice en otra, y la ventana de tiempo debe comprobarse con un reloj sincronizado por NTP. El AuthnContextClassRef es el equivalente en SAML de una declaración sobre la robustez de la autenticación, y es la forma en que un SP exige autenticación multifactor. Los atributos suelen nombrarse con identificadores de objeto LDAP, y por eso las guías de integración están llenas de cadenas como urn:oid:1.3.6.1.4.1.5923.1.1.1.1.
Flujos y bindings
Un binding describe cómo viaja un mensaje SAML sobre HTTP. Hay dos que importan.
HTTP-Redirect coloca en un parámetro de consulta un mensaje comprimido con deflate, codificado en base64 y codificado para URL, con la firma en un parámetro aparte. Es adecuado para mensajes pequeños, como una petición de autenticación, y está limitado por la longitud de la URL.
HTTP-POST pone el mensaje codificado en base64 en un campo oculto de formulario que una pequeña página con envío automático manda al otro extremo. Las respuestas que llevan aserciones usan siempre este binding, porque son demasiado grandes para una URL.
El SSO iniciado por el SP es el flujo preferible. El usuario pide una página protegida, el SP construye una AuthnRequest con un ID único y redirige el navegador al IdP; el IdP autentica al usuario y después envía por POST una Response que contiene la aserción al Assertion Consumer Service del SP.
GET /idp/profile/SAML2/Redirect/SSO?SAMLRequest=fVLLTsMwEPwVy3fHTkI...
&RelayState=%2Freports%2Fq3
&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256
&Signature=Xk9c2Fq... HTTP/1.1
Host: idp.university.example
POST /saml/acs HTTP/1.1
Host: app.example.com
Content-Type: application/x-www-form-urlencoded
SAMLResponse=PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6...&RelayState=%2Freports%2Fq3
RelayState transporta el estado propio del SP —normalmente la página que el usuario quería ver al principio— y debe tratarse como entrada no confiable: valídalo como ruta relativa o habrás construido una redirección abierta. Como las cargas útiles van en base64, un decodificador base64 es la forma más rápida de leer un mensaje capturado mientras depuras una integración, aunque el código de producción debe trabajar siempre con el documento ya parseado y verificado.
El SSO iniciado por el IdP parte de un enlace en un portal: el IdP envía una aserción no solicitada sin InResponseTo. Es cómodo y más débil, porque el SP no tiene ninguna petición propia con la que correlacionar la respuesta. Dale soporte solo cuando un cliente insista, y compénsalo con tiempos de vida cortos y un control estricto de uso único de los identificadores de aserción.
Metadatos y certificados
Los metadatos son la descripción legible por máquina de una parte: su identificador de entidad, sus endpoints, los formatos de NameID que admite y, sobre todo, sus certificados.
<md:EntityDescriptor entityID="https://app.example.com/saml/metadata"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"
AuthnRequestsSigned="true" WantAssertionsSigned="true">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data><ds:X509Certificate>MIIDdzCCAl+gAwIBAgIE...</ds:X509Certificate></ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:AssertionConsumerService index="0"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://app.example.com/saml/acs"/>
<md:SingleLogoutService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://app.example.com/saml/slo"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
Dos hábitos operativos evitan la mayoría de las caídas de SAML. Sirve los metadatos en una URL HTTPS estable y consume los del socio de la misma manera, de forma periódica, en lugar de intercambiar archivos por correo. Y rota los certificados con solapamiento: publica el nuevo junto al antiguo, espera a que todos los socios hayan actualizado, cambia la clave de firma y, por último, retira el certificado antiguo. Un certificado que caduca a medianoche sin solapamiento es el clásico incidente de federación del lunes por la mañana.
Validar la firma, con cuidado
La seguridad de SAML descansa por completo en las firmas digitales XML, y las firmas XML son más difíciles de lo que parecen porque la firma referencia una parte del documento mediante un identificador en lugar de cubrir todos los bytes. Esa indirección dio lugar a la familia de ataques de signature wrapping: el atacante toma una aserción firmada legítimamente, la envuelve o la reubica dentro del documento e inserta una aserción falsificada que el parser de la aplicación acaba leyendo. La firma sigue verificándose —sobre el elemento original, ahora oculto— mientras la aplicación actúa sobre la versión del atacante.
Las defensas son concretas:
- Verifica primero y lee después. Valida la firma y extrae el sujeto y los atributos del elemento exacto que se firmó, nunca de una nueva consulta XPath sobre todo el documento.
- Usa una biblioteca SAML mantenida, no un kit de herramientas XML de propósito general. El tratamiento correcto de las referencias, la canonicalización y la identidad del elemento firmado no es algo que convenga reimplementar.
- Decide de antemano qué debe ir firmado —la respuesta, la aserción o ambas— y rechaza todo lo que no cumpla esa política. Una aserción sin firmar dentro de una respuesta firmada no es segura automáticamente.
- Fija el certificado a partir de los metadatos. No confíes nunca en un certificado incluido en el propio mensaje entrante, y comprueba el identificador de entidad del emisor frente a la clave que esperas.
- Desactiva la resolución de entidades externas y las DTD en el parser. El procesamiento de entidades externas XML convierte un endpoint de login en una primitiva de lectura de archivos; la guía de procesamiento de XML cubre los ajustes del parser implicados.
- Aplica el conjunto completo de condiciones: audiencia,
NotBefore,NotOnOrAfter,Recipient,InResponseToy uso único del identificador de la aserción. - Exige SHA-256 o algo más robusto. Rechaza los algoritmos de firma SHA-1 y las claves RSA de menos de 2048 bits.
Single logout y mapeo de atributos
El single logout propaga un cierre de sesión desde una aplicación a todo el círculo de confianza: la parte que lo inicia envía una LogoutRequest que indica el SessionIndex, y el IdP la reenvía a cada uno de los demás SP. En la práctica es frágil: basta un SP inaccesible o un navegador que bloquee una cadena de redirecciones para que la secuencia se quede a medias. Por eso muchos despliegues cierran la sesión localmente, redirigen al IdP para terminar la sesión central y aceptan que las demás aplicaciones caduquen por sí solas. Si un cierre de sesión global fiable es un requisito, trátalo como una restricción de diseño desde el principio, no como una casilla que marcar.
El mapeo de atributos es la parte ingrata de toda integración. El IdP entrega lo que la política de la organización permite, con nombres que tú no eliges, y tu aplicación debe traducirlos a sus propios roles. Dos reglas ahorran muchos disgustos: nunca conviertas un nombre de grupo del directorio del cliente en una autoridad fija en tu código —mapéalo mediante configuración— y trata los valores de los atributos como cadenas no confiables que necesitan la misma validación y codificación de salida que cualquier otra entrada.
¿SAML u OpenID Connect?
| Aspecto | SAML 2.0 | OpenID Connect |
|---|---|---|
| Formato | XML con firmas digitales XML | JSON con JWS |
| Establecimiento de la confianza | Intercambio de metadatos y certificados | Documento de discovery más JWKS |
| Autorización de APIs | No contemplada | Basada en access tokens de OAuth 2.0 |
| Soporte para móviles y SPA | Incómodo, centrado en el navegador | Diseñado para ello |
| Alcance empresarial y académico | Muy amplio, consolidado | En crecimiento, universal en productos nuevos |
| Riesgo de implementación | El manejo de firmas no perdona | Más sencillo, aunque validar los tokens sigue siendo clave |
Para una integración nueva en la que puedas elegir, opta por OpenID Connect: la criptografía es más fácil de hacer bien, la misma infraestructura protege tus APIs mediante OAuth 2.0 y los clientes móviles son ciudadanos de primera. Elige SAML cuando la otra parte solo hable SAML, lo que en contextos empresariales y académicos suele zanjar la cuestión. Muchos productos soportan ambos, y un proveedor de identidad moderno hará sin problema de IdP SAML para una aplicación y de OpenID Provider para la siguiente.
Puntos clave
- SAML federa la autenticación haciendo que un proveedor de servicio confíe en una aserción XML firmada por un proveedor de identidad, con la confianza anclada en los metadatos intercambiados.
- Las condiciones de una aserción —audiencia, ventana de tiempo, destinatario e
InResponseTo— son controles de seguridad que el consumidor debe aplicar, no documentación. - Los flujos iniciados por el SP, con el binding HTTP-POST para las respuestas, son la opción segura por defecto; las aserciones no solicitadas iniciadas por el IdP pierden la protección contra el replay.
- Unos metadatos servidos por HTTPS y actualizados periódicamente, con certificados solapados, convierten la rotación de claves en un cambio rutinario.
- Valida la firma con una biblioteca SAML de verdad, lee solo el elemento firmado, fija los certificados a partir de los metadatos y desactiva las entidades externas.
- Prefiere OpenID Connect para los proyectos nuevos; soporta SAML cuando la otra parte lo requiera, y cuenta con que el single logout necesitará un diseño deliberado.
Fuentes y lecturas recomendadas
Preguntas frecuentes
- ¿SAML está obsoleto?
- Está maduro, no obsoleto. Las nuevas integraciones de consumo y móviles usan OpenID Connect, pero SAML sigue siendo la opción por defecto en las federaciones de educación superior, los servicios de la administración pública y los grandes parques de software empresarial, y nadie va a reescribir esos despliegues. Si vendes software a empresas, soportar SAML suele ser un requisito de compras más que una preferencia técnica.
- ¿Por qué se desaconseja el SSO iniciado por el IdP?
- Porque el proveedor de servicio recibe una aserción no solicitada, sin ninguna petición propia con la que correlacionarla, lo que elimina la protección natural contra el replay y el CSRF que aporta InResponseTo. Un atacante que capture una aserción, o que consiga que el navegador de una víctima envíe una, puede desencadenar un inicio de sesión que la víctima nunca empezó. Si el flujo es inevitable, impón tiempos de vida cortos a las aserciones y un control estricto de uso único.
- ¿Tengo que cifrar las aserciones además de firmarlas?
- La firma es imprescindible para la confianza; el cifrado protege la confidencialidad de los atributos. Como las aserciones viajan a través del navegador, todo lo sensible que contengan es visible para el usuario y para cualquier cosa que se ejecute en ese navegador. Si la aserción solo lleva un identificador opaco sobre TLS, basta normalmente con firmarla; si lleva datos personales, roles o permisos que no le mostrarías al usuario, cifra la aserción.
- ¿Cómo se debe gestionar la rotación de certificados?
- Publica, durante un periodo de solapamiento, metadatos que contengan tanto el certificado de firma saliente como el entrante, para que los verificadores acepten cualquiera de los dos. Cambia la clave de firma solo cuando todos los socios hayan actualizado su copia de los metadatos y, después, vuelve a publicarlos sin el certificado antiguo. Consumir los metadatos desde una URL de forma periódica, en lugar de intercambiar archivos por correo, es lo que convierte esto en un cambio rutinario y no en una caída.