Autenticação
A API emite os próprios tokens (ASP.NET Identity local) e atende três tipos de cliente com endpoints dedicados. Schemas completos no spec OpenAPI.
Fluxo browser (cookie BFF)
Sessão em cookie HttpOnly+Secure+SameSite — zero token no JavaScript. Escritas
exigem o header X-XSRF-TOKEN, obtido em GET /v1/auth/csrf — endpoint anônimo: o SPA
pode buscar o token antes mesmo do login. O antiforgery só é validado quando o cookie de
sessão autentica o caller (cookie presente e sessão válida); um cookie ausente,
expirado ou inválido não exige token, e clientes Bearer são imunes.
/csrf é anônimo e a validação exige sessão válidaEmitir token antiforgery não depende de identidade, e CSRF só faz sentido para uma credencial ambiente que de fato confere autoridade. Gatear a validação por presença do cookie (em vez de sessão autenticada) e exigir login para obter o token travava o usuário quando o cookie expirava: não dava para logar (o cookie morto "exigia" CSRF) nem para obter o token (precisava estar logado). Corrigido no canon — ADR-008 do template.
| Endpoint | Request | Response |
|---|---|---|
POST /v1/auth/session | { email, password } | 204 + Set-Cookie |
POST /v1/auth/session/refresh | — (cookie) | 204 + cookie renovado |
POST /v1/auth/session/logout | — (cookie) | 204 + cookie removido |
GET /v1/auth/me | — (cookie ou Bearer) | { id, userName, roles[] } |
GET /v1/auth/csrf | — | { token } |
Fluxo mobile (Bearer JWT + refresh rotation)
| Endpoint | Request | Response |
|---|---|---|
POST /v1/auth/token | { email, password } | { accessToken, accessTokenExpiresAt, refreshToken } |
POST /v1/auth/token/refresh | { refreshToken } | novo par (refresh token rotacionado — o antigo é invalidado) |
Envie o access token em Authorization: Bearer <token>.
Fluxo service-to-service (client credentials)
| Endpoint | Request | Response |
|---|---|---|
POST /v1/auth/clients/token | { clientId, clientSecret } | { accessToken, expiresAt } |
Tokens de serviço não têm refresh — renove com novas credenciais ao expirar.
Validação dos tokens (JWKS)
Os JWTs são RSA assimétricos, assinados pela chave do ISigningKeyProvider (ephemeral
em dev, PEM em produção). Qualquer validador — inclusive a própria API — usa as chaves
públicas publicadas em:
GET /.well-known/jwks.json
Autorização
Os dois schemes desembocam no mesmo ICurrentUser: as roles do usuário são resolvidas
para permissões via tabela RolePermissions (cache de 5 min). Cada endpoint declara sua
permissão (Orders.Create, etc.) — 401 sem credencial válida, 403 sem a permissão.
Seed do canon: Admin (Create/Approve/Read), Operator (Create/Read), Viewer (Read).