Como projetar sistemas de autenticação federada
1. Fundamentos da Autenticação Federada
A autenticação federada é um mecanismo que permite que usuários acessem múltiplos sistemas ou aplicações utilizando uma única identidade gerenciada por um provedor externo. Os três componentes fundamentais são:
- Provedor de Identidade (IdP): Responsável por autenticar o usuário e emitir credenciais digitais (tokens, asserções)
- Provedor de Serviço (SP): A aplicação que consome a identidade federada para conceder acesso
- Identidade Federada: O vínculo entre a identidade do usuário no IdP e sua conta no SP
Diferentemente do SSO tradicional (que opera dentro de um único domínio administrativo), a federação estabelece confiança entre domínios distintos. Enquanto a autenticação centralizada usa um único banco de usuários, a federação delega a autenticação a terceiros confiáveis.
Casos de uso comuns incluem:
- Login com Google, Facebook ou Apple em aplicações terceiras
- Ambientes corporativos com múltiplas subsidiárias usando um IdP central
- Portais governamentais que integram identidades de diferentes órgãos
2. Protocolos e Padrões Principais
SAML 2.0
O Security Assertion Markup Language (SAML) 2.0 utiliza asserções XML para transportar informações de autenticação. Seus elementos principais:
<saml:Assertion>
<saml:Issuer>https://idp.exemplo.com</saml:Issuer>
<saml:Subject>
<saml:NameID>usuario@exemplo.com</saml:NameID>
</saml:Subject>
<saml:Conditions NotBefore="2024-01-01T00:00:00Z"
NotOnOrAfter="2024-01-01T01:00:00Z"/>
<saml:AuthnStatement AuthnInstant="2024-01-01T00:00:00Z"/>
<saml:AttributeStatement>
<saml:Attribute Name="email">
<saml:AttributeValue>joao@exemplo.com</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
Fluxos suportados:
- SP-initiated: Usuário acessa o SP, que redireciona ao IdP
- IdP-initiated: Usuário autentica no IdP e é redirecionado ao SP
OpenID Connect (OIDC)
Construído sobre OAuth 2.0, o OIDC adiciona uma camada de identidade. O ID Token (JWT) contém as claims do usuário:
{
"iss": "https://accounts.google.com",
"sub": "1234567890",
"aud": "minha-aplicacao-id",
"exp": 1704067200,
"iat": 1704063600,
"email": "usuario@exemplo.com",
"email_verified": true
}
Comparação prática
| Critério | SAML 2.0 | OIDC | JWT Federado |
|---|---|---|---|
| Formato do token | XML | JSON (JWT) | JSON |
| Complexidade | Alta | Média | Baixa |
| Suporte mobile | Limitado | Nativo | Bom |
| Ecossistema enterprise | Maduro | Crescente | Emergente |
Escolha SAML para integrações legadas ou governamentais. Prefira OIDC para aplicações modernas e mobile. Use JWT federado em sistemas internos com confiança pré-estabelecida.
3. Arquitetura de Confiança e Metadados
O estabelecimento de confiança exige:
- Certificados e chaves públicas: O SP valida assinaturas do IdP usando sua chave pública
- Metadados federados: Documento XML contendo endpoints, certificados e configurações
Exemplo de metadados SAML do SP:
<md:EntityDescriptor entityID="https://sp.exemplo.com/metadata">
<md:SPSSODescriptor>
<md:KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Certificate>MIIB...==</ds:X509Certificate>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:AssertionConsumerService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://sp.exemplo.com/acs"
index="1"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
Gerenciamento de metadados:
- Estático: Troca manual de arquivos XML entre administradores
- Dinâmico: Uso de Dynamic Discovery ou endpoints de metadados assinados
Para revogação e rotação de chaves, implemente:
- Cache com TTL para metadados (ex: 24 horas)
- Monitoramento de expiração de certificados
- Processo automatizado de rotação com sobreposição de validade
4. Fluxos de Autenticação e Autorização
Fluxo de login federado (OIDC - Authorization Code Flow)
1. Usuário acessa SP e clica em "Login com IdP"
2. SP redireciona para IdP:
GET /authorize?response_type=code
&client_id=sp-client-id
&redirect_uri=https://sp.exemplo.com/callback
&scope=openid%20email%20profile
&state=xyz123
3. Usuário autentica no IdP (login + senha)
4. IdP redireciona de volta ao SP:
GET /callback?code=auth-code-123&state=xyz123
5. SP troca o código por tokens:
POST /token
grant_type=authorization_code
code=auth-code-123
client_id=sp-client-id
client_secret=sp-client-secret
6. IdP retorna ID Token + Access Token
7. SP valida ID Token e cria sessão local
Mapeamento de atributos
Transformação entre claims do IdP e atributos do SP:
// Mapeamento de claims IdP -> SP
{
"sub": "user_id",
"email": "email_address",
"given_name": "first_name",
"family_name": "last_name",
"custom:role": "user_role"
}
Autorização federada (ABAC)
Política baseada em atributos federados:
PERMITIR ACESSO SE:
user.role == "admin" E
user.department == "engenharia" E
current_time BETWEEN "09:00" AND "18:00"
5. Segurança e Mitigação de Riscos
Ameaças comuns e contramedidas
| Ameaça | Mitigação |
|---|---|
| Sequestro de sessão | Uso de state parameter, HttpOnly cookies |
| Replay de tokens | Nonce, timestamps, jti único |
| CSRF | State parameter com hash, SameSite cookies |
| SAML assertion injection | Validação de Audience, Recipient e Destination |
Práticas essenciais
// Validação obrigatória no SP
1. Verificar assinatura do token (JWT ou SAML)
2. Validar audience (aud) ou AudienceRestriction
3. Checar expiração (exp, NotOnOrAfter)
4. Confirmar issuer (iss) confiável
5. Validar nonce/state para prevenir replay
6. Verificar se o token não foi revogado (blacklist)
Logs de auditoria federada
{
"timestamp": "2024-01-01T12:00:00Z",
"event": "authentication_attempt",
"user_id": "joao@exemplo.com",
"idp": "https://accounts.google.com",
"sp": "https://app.exemplo.com",
"result": "success",
"ip_address": "192.168.1.100",
"session_id": "abc-123-def"
}
6. Projetando para Resiliência e Escalabilidade
Estratégias de failover
// Configuração de múltiplos IdPs
idps:
primary:
url: https://idp1.exemplo.com
metadata: /etc/metadata/idp1.xml
priority: 1
secondary:
url: https://idp2.exemplo.com
metadata: /etc/metadata/idp2.xml
priority: 2
// Lógica de failover
SE primary_idp_unavailable THEN
redirecionar para secondary_idp
registrar evento de failover
Cache e performance
- Cache de metadados federados (TTL: 1 hora)
- Cache de chaves públicas (TTL: 12 horas)
- Cache de sessões federadas (TTL: conforme política)
Tratamento de timeouts
// Configuração de retry com backoff
retry_policy:
max_attempts: 3
initial_delay_ms: 1000
backoff_multiplier: 2
max_delay_ms: 10000
// Degradação graciosa
SE idp_unavailable THEN
exibir mensagem: "Serviço de autenticação temporariamente indisponível"
oferecer reautenticação em 30 segundos
7. Implementação Prática e Padrões de Código
Estrutura de endpoints do SP
/sp:
/login # Inicia fluxo federado
/callback # Recebe resposta do IdP
/logout # Logout federado (SLO)
/metadata # Metadados do SP
/userinfo # Informações do usuário autenticado
Exemplo de validação de token JWT/OIDC
// Validação de ID Token
function validar_id_token(token, expected_audience, trusted_issuers):
// 1. Decodificar header para obter kid
header = base64_decode(token.header)
kid = header.kid
// 2. Buscar chave pública no cache
public_key = cache.get(kid)
if public_key is None:
public_key = fetch_jwks_from_idp()
cache.set(kid, public_key, ttl=3600)
// 3. Verificar assinatura
if not verify_signature(token, public_key):
throw "Assinatura inválida"
// 4. Validar claims
payload = base64_decode(token.payload)
if payload.iss not in trusted_issuers:
throw "Issuer não confiável"
if payload.aud != expected_audience:
throw "Audience inválida"
if payload.exp < current_timestamp():
throw "Token expirado"
if payload.nonce != session.get('nonce'):
throw "Nonce inválido"
return payload
Configuração de trust store
// trust-store.json
{
"idps": [
{
"entity_id": "https://accounts.google.com",
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
"certificates": [
{
"kid": "abc123",
"algorithm": "RS256",
"expires": "2025-01-01T00:00:00Z"
}
],
"metadata_url": "https://accounts.google.com/.well-known/openid-configuration"
}
],
"revocation": {
"type": "blacklist",
"endpoint": "https://auth.exemplo.com/revoked-tokens",
"cache_ttl": 300
}
}
Boas práticas de logging e monitoramento
// Eventos críticos para monitoramento
- authentication_success: Contagem de logins bem-sucedidos
- authentication_failure: Contagem de falhas por motivo
- token_validation_error: Erros de validação (assinatura, expiração)
- idp_timeout: Timeouts de comunicação com IdP
- certificate_expiring: Certificados próximos da expiração
- metadata_change: Alterações em metadados federados
// Métricas para dashboard
- Taxa de sucesso de autenticação (>99%)
- Latência média de resposta do IdP (<500ms)
- Número de sessões federadas ativas
- Distribuição por IdP utilizado
Testes de integração federada
// Cenários de teste obrigatórios
1. Login bem-sucedido com IdP primário
2. Login com IdP secundário (failover)
3. Token expirado retorna erro 401
4. Token com assinatura inválida retorna erro
5. Audience incorreta é rejeitada
6. Nonce repetido é rejeitado (replay)
7. Logout federado encerra sessão em todos os SPs
8. Rotação de chaves do IdP continua funcionando
9. Timeout do IdP aciona degradação graciosa
10. Metadados expirados forçam recarregamento
Referências
- OpenID Connect Specification — Documentação oficial do protocolo OpenID Connect, incluindo fluxos de autenticação e validação de tokens
- SAML 2.0 Technical Overview — Guia técnico completo sobre SAML 2.0 da OASIS, com detalhes de bindings e profiles
- OAuth 2.0 Authorization Framework — RFC 6749 que define o framework de autorização OAuth 2.0, base para o OpenID Connect
- JSON Web Token (JWT) RFC 7519 — Especificação oficial do formato JWT, incluindo estrutura de claims e algoritmos de assinatura
- NIST SP 800-63C: Digital Identity Guidelines - Federation — Diretrizes do NIST para implementação segura de federação de identidades
- Auth0: Federated Identity Management Explained — Guia prático sobre gerenciamento de identidade federada com exemplos de configuração
- Keycloak: Server Administration Guide - Identity Brokering — Documentação oficial do Keycloak sobre federação de identidades e social login