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 cookiexadm_sessione 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 noAuthFilter— o login Google não afeta a API.- Views → login Google + cookie de sessão JWT HS256 (
xadm_session), gate nosecurity/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 CSRFxadm_login_csrf.POST /login/callback(JSON{credential, from, csrfToken}) → valida CSRF + Firebase ID token + domínio; emitexadm_session. Status:200 {redirect};400csrf/token;401token inválido;403domain_not_allowed;503JWKS indisponível.POST /logout→ expiraxadm_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 respondem503 {"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.