Segurança e identidade

SAML 2.0 e single sign-on: asserções, bindings e federação

Intermediário8 min de leituraAtualizado

Esta página foi traduzida do inglês com a ajuda de IA e conferida com o original. Ler a versão em inglês

O SAML 2.0 ainda sustenta o login único em universidades, órgãos de governo e grandes corporações, e integrar-se a ele significa ler XML em vez de JSON. Este guia explica o modelo de federação, a anatomia de uma asserção, os dois fluxos de iniciação e seus bindings, metadados e rotação de certificados, as armadilhas de assinatura que deram ao SAML sua má fama e quando escolhê-lo em vez do OpenID Connect.

O que você vai aprender

  • Explicar o modelo de federação e os papéis de provedor de identidade e provedor de serviço
  • Ler uma asserção SAML e identificar o sujeito, as condições, as declarações e a assinatura
  • Diferenciar fluxos iniciados pelo SP e pelo IdP, e os bindings Redirect e POST
  • Trocar metadados e fazer a rotação de certificados de assinatura sem indisponibilidade
  • Evitar os erros de validação de assinatura que levam a um bypass da autenticação
  • Decidir entre SAML e OpenID Connect para uma nova integração

Muito antes de os navegadores conversarem em JSON com provedores de identidade, as empresas precisavam que um único login abrisse uma dúzia de aplicações, algumas delas rodando em uma organização completamente diferente. O SAML 2.0, padronizado pela OASIS em 2005, resolveu isso com um vocabulário XML para produzir e transportar declarações sobre um usuário autenticado, e desde então sustenta discretamente federações universitárias, portais de governo e parques de aplicações corporativas. Se você vende software para grandes organizações, mais cedo ou mais tarde um cliente vai lhe mandar um arquivo de metadados em vez de um client secret.

Trabalhar com SAML é diferente de trabalhar com OpenID Connect em aspectos que vão além do formato de serialização. A confiança é estabelecida fora de banda, pela troca de certificados, e não pela obtenção de um documento de discovery; a segurança de toda a troca depende de assinaturas digitais XML, uma especificação famosa por suas arestas; e não existe o conceito de access token para chamar APIs. Este guia cobre o que você precisa para integrar corretamente e o que historicamente deu errado.

A federação e seus dois papéis

Single sign-on significa que o usuário se autentica uma vez e as aplicações seguintes aceitam essa autenticação em vez de pedi-la de novo. A federação estende isso para além das fronteiras de uma organização: a aplicação confia em uma asserção feita por um provedor de identidade que ela não controla, com base em um certificado trocado previamente.

  • O provedor de identidade (IdP) autentica o usuário e emite asserções. Normalmente há um por organização.
  • O provedor de serviço (SP) é a aplicação que consome a asserção. Ele nunca vê as credenciais do usuário.
  • A asserção é o documento XML assinado que carrega as declarações.
  • O círculo de confiança é o conjunto de partes que trocaram metadados e concordaram em aceitar as declarações umas das outras.

A consequência prática é que as credenciais ficam no diretório do empregador. Quando uma pessoa sai da organização, ela é desativada uma única vez, de forma centralizada, e todas as aplicações federadas deixam de admiti-la — o argumento do ciclo de vida da identidade, aprofundado em gestão de identidades e acessos.

Anatomia de uma asserção

Uma asserção é um elemento <saml:Assertion> com um emissor, uma assinatura, um sujeito, condições de validade e uma ou mais declarações. Sem o ruído dos namespaces, uma asserção realista fica assim.

<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 impõe obrigações ao consumidor. O formato do NameID determina se você recebe um identificador reutilizável: persistent fornece um pseudônimo estável e exclusivo para esse par com o SP, transient fornece um valor válido para uma única sessão, e emailAddress fornece algo legível, mas que pode mudar. As condições precisam ser aplicadas — a restrição de audiência é o que impede que uma asserção emitida para uma aplicação seja reaproveitada em outra, e a janela de tempo deve ser verificada com um relógio sincronizado por NTP. O AuthnContextClassRef é o equivalente, no SAML, a uma declaração sobre a força da autenticação, e é assim que um SP exige autenticação multifator. Os atributos costumam ser nomeados por identificadores de objeto LDAP, e é por isso que os guias de integração estão cheios de strings como urn:oid:1.3.6.1.4.1.5923.1.1.1.1.

Fluxos e bindings

Um binding descreve como uma mensagem SAML trafega sobre HTTP. Dois deles importam.

O HTTP-Redirect coloca em um parâmetro de query uma mensagem comprimida com deflate, codificada em base64 e codificada para URL, com a assinatura em um parâmetro separado. Ele serve para mensagens pequenas, como uma requisição de autenticação, e é limitado pelo tamanho da URL.

O HTTP-POST coloca a mensagem codificada em base64 em um campo oculto de formulário, que uma pequena página com envio automático posta para o outro lado. As respostas que carregam asserções usam sempre esse binding, porque são grandes demais para uma URL.

O SSO iniciado pelo SP é o fluxo preferível. O usuário pede uma página protegida, o SP monta uma AuthnRequest com um ID único e redireciona o navegador para o IdP; o IdP autentica o usuário e depois envia via POST uma Response contendo a asserção para o Assertion Consumer Service do 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

O RelayState carrega o estado do próprio SP — geralmente a página que o usuário queria acessar originalmente — e deve ser tratado como entrada não confiável: valide-o como caminho relativo, ou você terá criado um open redirect. Como os payloads estão em base64, um decodificador base64 é o jeito mais rápido de ler uma mensagem capturada ao depurar uma integração, embora o código de produção deva sempre trabalhar a partir do documento já parseado e verificado.

O SSO iniciado pelo IdP começa a partir de um link em um portal: o IdP posta uma asserção não solicitada, sem InResponseTo. É prático, mas mais fraco, já que o SP não tem nenhuma requisição própria com a qual correlacionar a resposta. Dê suporte a ele apenas quando um cliente fizer questão, e compense com tempos de vida curtos e controle rigoroso de uso único dos identificadores de asserção.

Metadados e certificados

Os metadados são a descrição legível por máquina de uma parte: seu identificador de entidade, seus endpoints, os formatos de NameID que ela suporta e, principalmente, seus 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>

Dois hábitos operacionais evitam a maioria das quedas de SAML. Sirva os metadados em uma URL HTTPS estável e consuma os do parceiro da mesma forma, periodicamente, em vez de trocar arquivos por e-mail. E faça a rotação de certificados com sobreposição: publique o novo ao lado do antigo, espere até que todos os parceiros tenham atualizado, troque a chave de assinatura e, por fim, remova o certificado antigo. Um certificado que expira à meia-noite sem sobreposição é o clássico incidente de federação de segunda-feira de manhã.

Validação de assinatura, com cuidado

A segurança do SAML depende inteiramente de assinaturas digitais XML, e assinaturas XML são mais difíceis do que parecem, porque a assinatura referencia uma parte do documento por identificador em vez de cobrir todos os bytes. Essa indireção deu origem à família de ataques de signature wrapping: o atacante pega uma asserção assinada legitimamente, a envolve ou a realoca dentro do documento e insere uma asserção forjada que o parser da aplicação acaba lendo. A assinatura continua sendo verificada — sobre o elemento original, agora escondido — enquanto a aplicação age sobre a versão do atacante.

As defesas são específicas:

  • Verifique primeiro, leia depois. Valide a assinatura e então extraia o sujeito e os atributos do elemento exato que foi assinado, nunca de uma nova consulta XPath sobre o documento inteiro.
  • Use uma biblioteca SAML mantida, não um toolkit XML de uso geral. O tratamento correto de referências, da canonicalização e da identidade do elemento assinado não é algo para reimplementar.
  • Decida de antemão o que precisa ser assinado — a resposta, a asserção ou ambas — e rejeite tudo o que não atender a essa política. Uma asserção não assinada dentro de uma resposta assinada não é automaticamente segura.
  • Fixe o certificado a partir dos metadados. Nunca confie em um certificado embutido na própria mensagem recebida, e confira o identificador de entidade do emissor com a chave que você espera.
  • Desative a resolução de entidades externas e as DTDs no parser. O processamento de entidades externas XML transforma um endpoint de login em uma primitiva de leitura de arquivos; o guia de processamento de XML cobre as configurações de parser envolvidas.
  • Aplique o conjunto completo de condições: audiência, NotBefore, NotOnOrAfter, Recipient, InResponseTo e uso único do identificador da asserção.
  • Exija SHA-256 ou algo mais forte. Rejeite algoritmos de assinatura SHA-1 e chaves RSA com menos de 2048 bits.

Single logout e mapeamento de atributos

O single logout propaga um logout de uma aplicação para todo o círculo de confiança: a parte que o inicia envia uma LogoutRequest indicando o SessionIndex, e o IdP a repassa para cada um dos outros SPs. Na prática, é frágil — basta um SP inacessível ou um navegador que bloqueie uma cadeia de redirecionamentos para a sequência parar no meio. Por isso, muitas implantações fazem o logout local, redirecionam para o IdP para encerrar a sessão central e aceitam que as demais aplicações expirem naturalmente. Se um logout global confiável for um requisito, trate-o como uma restrição de design desde o início, e não como um item de checklist.

O mapeamento de atributos é a parte ingrata de toda integração. O IdP libera o que a política da organização permite, com nomes que você não escolhe, e sua aplicação precisa traduzi-los para os próprios papéis. Duas regras poupam muita dor de cabeça: nunca transforme um nome de grupo do diretório do cliente em uma autoridade fixa no código — faça o mapeamento via configuração — e trate os valores de atributos como strings não confiáveis, que exigem a mesma validação e o mesmo encoding de saída que qualquer outra entrada.

SAML ou OpenID Connect?

AspectoSAML 2.0OpenID Connect
FormatoXML com assinaturas digitais XMLJSON com JWS
Estabelecimento da confiançaTroca de metadados e certificadosDocumento de discovery mais JWKS
Autorização de APIsNão cobertaBaseada em access tokens do OAuth 2.0
Suporte a mobile e SPADesajeitado, centrado no navegadorProjetado para isso
Alcance corporativo e acadêmicoMuito amplo, consolidadoEm crescimento, universal em produtos novos
Risco de implementaçãoO tratamento de assinaturas não perdoaMais simples, mas a validação de tokens continua importante

Para uma nova integração em que você tenha escolha, fique com o OpenID Connect: a criptografia é mais fácil de acertar, a mesma infraestrutura protege suas APIs via OAuth 2.0, e clientes mobile são cidadãos de primeira classe. Escolha SAML quando a outra parte só falar SAML, o que, em contextos corporativos e acadêmicos, muitas vezes encerra a questão. Muitos produtos suportam os dois, e um provedor de identidade moderno atua tranquilamente como IdP SAML para uma aplicação e como OpenID Provider para a seguinte.

Principais pontos

  • O SAML federa a autenticação fazendo um provedor de serviço confiar em uma asserção XML assinada por um provedor de identidade, com a confiança ancorada nos metadados trocados.
  • As condições de uma asserção — audiência, janela de tempo, destinatário e InResponseTo — são controles de segurança que o consumidor precisa aplicar, não documentação.
  • Fluxos iniciados pelo SP, com o binding HTTP-POST para as respostas, são o padrão seguro; asserções não solicitadas iniciadas pelo IdP perdem a proteção contra replay.
  • Metadados servidos via HTTPS e atualizados periodicamente, com certificados sobrepostos, transformam a rotação de chaves em uma mudança de rotina.
  • Valide a assinatura com uma biblioteca SAML de verdade, leia apenas o elemento assinado, fixe os certificados a partir dos metadados e desative entidades externas.
  • Prefira OpenID Connect para projetos novos; dê suporte a SAML quando a outra parte exigir, e espere que o single logout exija um design deliberado.

Fontes e leituras complementares

Perguntas frequentes

O SAML está obsoleto?
Ele é maduro, não obsoleto. As novas integrações voltadas ao consumidor e a apps mobile usam OpenID Connect, mas o SAML continua sendo o padrão em federações acadêmicas, serviços de governo e grandes parques de software corporativo, e ninguém está reescrevendo essas implantações. Se você vende software para empresas, dar suporte a SAML costuma ser uma exigência de compras, não uma preferência técnica.
Por que o SSO iniciado pelo IdP é desaconselhado?
Porque o provedor de serviço recebe uma asserção não solicitada, sem nenhuma requisição própria com a qual correlacioná-la, o que elimina a proteção natural contra replay e CSRF que o InResponseTo oferece. Um atacante que capture uma asserção, ou que consiga fazer o navegador de uma vítima enviar uma, pode disparar um login que a vítima nunca iniciou. Quando o fluxo for inevitável, imponha tempos de vida curtos às asserções e um controle rigoroso de uso único.
Preciso criptografar as asserções além de assiná-las?
A assinatura é obrigatória para a confiança; a criptografia protege a confidencialidade dos atributos. Como as asserções trafegam pelo navegador, tudo o que houver de sensível nelas fica visível para o usuário e para qualquer coisa que rode nesse navegador. Se a asserção carrega apenas um identificador opaco sobre TLS, assinar costuma bastar; se ela carrega dados pessoais, papéis ou permissões que você não mostraria ao usuário, criptografe a asserção.
Como a rotação de certificados deve ser feita?
Publique, durante um período de sobreposição, metadados contendo tanto o certificado de assinatura que está saindo quanto o que está entrando, para que os verificadores aceitem qualquer um dos dois. Troque a chave de assinatura só depois que todos os parceiros tiverem atualizado sua cópia dos metadados e, em seguida, republique-os sem o certificado antigo. Consumir os metadados a partir de uma URL, de forma periódica, em vez de trocar arquivos por e-mail, é o que transforma isso em uma mudança de rotina e não em um incidente.