Pular para conteúdo

Etapa 07 — Autenticação Google nas views

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-07

O setup operacional (envs Firebase, cookies) vive no runbook operacao/google-auth. Esta página é o desenho.

Histórico: esta etapa descreve o gate via AuthFilter (filtro caseiro). O mecanismo foi depois migrado para o micronaut-security nativo (AuthenticationFetcher + SecurityRule + ExceptionHandler) preservando o comportamento — ver etapa 08 e a decisão 0018. Os envs, o cookie xadm_session e a UX continuam idênticos.

1. Contexto e escopo

As telas server-rendered (/, /processamentos, /admin, /admin/configuracoes) são operadas por humanos da X-Adm e não podem ficar públicas. Diferente da API (consumida por máquina, Bearer estático), elas precisam de login humano — resolvido com Google/Firebase restrito ao domínio @xadm.com.br.

Dentro do escopo: o gate das views; a sessão; o CSRF; o comportamento sem envs (dev/test vs prod).

Fora do escopo: a auth da API (/api/**, Bearer estático — decisão 0011); não mexer nela ao trabalhar nas views.

2. Componentes

flowchart TB
    user[Usuário X-Adm] -->|login Google| fb[Firebase]
    fb -->|ID token| login[LoginController]
    login -->|cookie xadm_session<br/>JWT HS256| browser[Browser]
    browser -->|cookie| filter[security/AuthFilter]
    filter -->|email @xadm.com.br| views[Views /processamentos, /admin]
    filter -.->|sem cookie / inválido| nega[302 /login ou 503]

3. Fluxos principais

3.1 Duas camadas independentes (decisão 0011)

  • /api/** → Bearer estático (@Secured("ROLE_API")). /api/** é whitelisted no AuthFilter — o login Google não afeta a API.
  • Views → login Google + cookie de sessão JWT HS256 (xadm_session), gate no security/AuthFilter (@Filter("/**"), roda antes do SecurityFilter do micronaut-security), restrito a @xadm.com.br.

3.2 Login (CSRF double-submit)

  • GET /login → renderiza Firebase JS SDK + grava cookie CSRF xadm_login_csrf.
  • POST /login/callback (JSON {credential, from, csrfToken}) → valida CSRF + Firebase ID token + domínio; emite xadm_session. Status: 200 {redirect}; 400 csrf/token; 401 token inválido; 403 domain_not_allowed; 503 JWKS indisponível.
  • POST /logout → expira xadm_session, 303 → /login.

3.3 Sem envs AUTH_* — bypass vs fail-closed

"Auth configurado" ≡ firebaseProjectId + firebaseApiKey + firebaseAuthDomain + firebaseAppId + sessionSecret todos preenchidos. Comportamento do AuthFilter:

  • Configurado → filtro ativo (exige xadm_session).
  • Ausente em dev/test → bypass (views públicas, para desenvolvimento).
  • Ausente fora de dev/test → fail-closed: views respondem 503 {"error":"auth_not_configured"} — nunca abre por engano.

4. Acesso efetivo por endpoint

O intercept-url-map (micronaut-security) marca como isAnonymous(): /health, /swagger/**, /swagger-ui/**, /public/**, /css/**, /images/** (estes dois últimos são os assets do kit de UI — CSS/logo carregam na tela de login, antes da sessão). A proteção real das views vem do AuthFilter (login Google) por cima.

Grupo Acesso efetivo
POST /api/xls/processar, /api/transporte/admin/** Bearer (ROLE_API)
Views /, /processamentos, /admin/** login Google (ativo); públicas em dev/test; 503 em prod sem envs
GET /api/transporte/processamentos/** (JSON), /health, /swagger*, /public/**, /css/**, /images/**, /login, /logout anônimos

Whitelist do AuthFilter (dispensam sessão): exatos /health, /favicon.ico, /login, /logout; prefixos /health/, /swagger/, /swagger-ui, /login/, /api/, /public/, /css/, /images/. As duas listas (o intercept-url-map do YAML e a whitelist Java do AuthSupport) andam juntas — public novo entra nas duas.

5. Configuração

Envs AUTH_* → AuthSettings: AUTH_FIREBASE_PROJECT_ID, AUTH_FIREBASE_API_KEY, AUTH_FIREBASE_AUTH_DOMAIN, AUTH_FIREBASE_APP_ID, AUTH_SESSION_SECRET, AUTH_SESSION_TTL_SECONDS, AUTH_COOKIE_SECURE, AUTH_XADM_EMAIL_DOMAIN. Setup detalhado: operacao/google-auth.

6. Decisões

Nº Decisão
0011 Autenticação em duas camadas

7. Riscos

  • Deploy de produção sem as envs AUTH_* → fail-closed (503), não exposição.
  • Vazamento do segredo da sessão (AUTH_SESSION_SECRET) → rotação; secrets no Coolify.