Ir para o conteúdo

Verificação de Email e Autenticação Multifator

Um pipeline de tokens perfeito não vale nada se a pessoa errada consegue obter um token. Por isso o Wittgenstein combina suas bibliotecas de tratamento de tokens com forte garantia de identidade no provedor de identidade: toda conta é vinculada a um endereço de email verificado, e o acesso sensível exige um segundo fator.

Nada disso vive no código da aplicação. É imposto pelo Keycloak antes de qualquer token ser emitido, então toda aplicação da plataforma herda essas garantias — e não consegue enfraquecê-las por acidente.

A escada de garantia

Nível O que o Keycloak comprova Imposto por
1 — Identidade verificada O usuário controla a caixa de email cadastrada Required action VERIFY_EMAIL
2 — Identidade verificada + posse …e possui um segundo fator registrado Autenticador TOTP ou WebAuthn / passkey
Recuperação Um fator ou senha perdidos podem ser redefinidos sem que um administrador manipule um segredo Links de ação por email assinados e com expiração

As aplicações leem o nível alcançado no token (claim acr) e decidem o que cada rota exige.

Verificação de email

As contas são criadas não verificadas. Até o usuário provar a posse do endereço, o Keycloak não conclui o login — a required action VERIFY_EMAIL interrompe o fluxo e envia um link assinado.

sequenceDiagram
    participant U as Usuário
    participant KC as Keycloak
    participant SMTP as Relay de email
    participant M as Caixa de entrada

    U->>KC: Primeiro login (senha)
    KC->>KC: Required action: VERIFY_EMAIL
    KC->>SMTP: Email de verificação (link assinado e com expiração)
    SMTP->>M: Entrega com TLS autenticado
    U->>M: Abre a mensagem e clica no link
    M->>KC: GET action-token
    KC->>KC: emailVerified = true
    KC-->>U: Continua o login → token emitido

Por que isso importa:

  • Bloqueia contas com erro de digitação e squatting — ninguém consegue registrar um endereço que não possui.
  • Torna o email um canal de recuperação confiável — redefinições de senha e de fator vão para uma caixa comprovada, e não apenas digitada.
  • Torna os claims de email seguros de usar — os serviços podem confiar em email_verified ao vincular ou provisionar identidades.

A entrega é feita pelo relay SMTP autenticado da própria plataforma, então o email de verificação não depende de terceiros.

Autenticação multifator

O fluxo de navegador do Keycloak é estendido com uma etapa de segundo fator. Fatores suportados:

Fator Tipo Observações
TOTP App autenticador (qualquer app RFC 6238) Cadastrado pela required action CONFIGURE_TOTP
WebAuthn / passkeys Chave de hardware, autenticador da plataforma Resistente a phishing: a credencial é vinculada ao origin do site
Códigos de recuperação Códigos de uso único Alternativa offline quando o dispositivo é perdido

O MFA pode ser aplicado como política, e não como configuração por usuário:

  • Sempre — todos os usuários do realm.
  • Por papel ou grupo — por exemplo, quem tem um papel administrativo recebe o desafio; usuários somente leitura, não (fluxos condicionais do Keycloak).
  • Step-up — o usuário entra no nível 1 e só recebe o pedido de segundo fator ao acessar algo que exija o nível 2.

Exigindo step-up na sua API

O Keycloak registra o nível de autenticação no claim acr. Como o OidcMiddleware já interpretou o token da requisição, uma rota pode exigir o nível mais forte em poucas linhas:

from fastapi import Depends, HTTPException
from wittgenstein_oidc_backend import get_current_payload


def require_mfa(payload: dict = Depends(get_current_payload)) -> dict:
    if int(payload.get("acr", "0")) < 2:          # 2 = senha + segundo fator
        raise HTTPException(
            status_code=401,
            detail="step-up required",
            headers={"WWW-Authenticate": 'Bearer error="insufficient_user_authentication"'},
        )
    return payload


@app.delete("/tenants/{tenant_id}", dependencies=[Depends(require_mfa)])
async def delete_tenant(tenant_id: str): ...

A SPA reage a essa resposta redirecionando ao Keycloak com acr_values=2; o usuário conclui o segundo fator e volta com um token que satisfaz a rota.

Alterações sensíveis na conta nunca passam pela aplicação. Para trocar a senha, a app pede ao Keycloak que envie ao usuário um link de required action; o usuário escolhe a nova senha na página do próprio Keycloak, onde valem a política de senhas e a proteção contra força bruta. A aplicação nunca vê, armazena nem transmite a senha.

curl -s -X PUT "https://auth.example.com/admin/realms/acme/users/$USER_ID/execute-actions-email?lifespan=3600" \ -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \ -d '["UPDATE_PASSWORD"]' -o /dev/null -w "%{http_code}\n"204# o usuário agora tem, na caixa de entrada, um link de uso único e válido por uma hora

O mesmo mecanismo pode solicitar CONFIGURE_TOTP (recadastrar um fator), VERIFY_EMAIL (reverificar) ou UPDATE_PROFILE. Os links são assinados, de propósito único e de curta duração.

Privilégio mínimo para quem chama

O serviço que dispara esses emails usa um client de service account dedicado, com apenas os papéis de realm-management de que precisa (view-users, manage-users), nunca uma credencial de administrador completa.

Reforço de sessão e bloqueio

A garantia é tão forte quanto a sessão que vem depois dela:

  • Access tokens de vida curta (minutos), com timeout de inatividade deslizante e um máximo absoluto de sessão.
  • Rotação do refresh token, mantido em um cookie HttpOnly (veja OIDC e Segurança de Tokens).
  • Detecção de força bruta bloqueia temporariamente uma conta após falhas repetidas, de modo que o segundo fator não possa ser vencido por tentativa e erro.
  • Política de senhas (tamanho, histórico, lista de bloqueio) avaliada pelo Keycloak, em um só lugar.

Verifique a configuração

curl -s https://auth.example.com/realms/acme/.well-known/openid-configuration | jq '.acr_values_supported'[
"0",
"1",
"2"
]
curl -s -H "Authorization: Bearer $TOKEN" https://app.example.com/api/tenants/t-1 -X DELETE -o /dev/null -w "%{http_code}\n"401# um token de nível 1 é recusado em uma rota de nível 2 até o usuário concluir o MFA

Implantando o MFA com segurança

Comece pelos papéis administrativos, confirme que os códigos de recuperação e os links de email funcionam de ponta a ponta, e só então amplie a política. Como a imposição vive no IdP, ampliá-la nunca exige um deploy de nenhuma aplicação.