Autenticação é a verificação de quem você é; autorização é a decisão, a cada requisição, do que você pode fazer. Todo sistema seguro precisa das duas. O hotel torna isso concreto: seu documento na recepção é autenticação; o cartão que abre o quarto 412 — e somente o quarto 412 — é autorização. São perguntas diferentes, feitas em momentos diferentes, respondidas por mecanismos diferentes, e que falham de formas diferentes — e é por isso que sistemas que as misturam acabam entregando os dois tipos de violação.
Principais pontos
| Pergunta | Resposta |
|---|---|
| Autenticação (AuthN) | Quem é você? — credenciais → identidade, uma vez por session |
| Autorização (AuthZ) | O que você pode fazer? — políticas → permitir/negar, toda requisição |
| Os códigos HTTP | 401 = não autenticado (um nome infeliz) · 403 = conhecido e recusado |
| A divisão dos protocolos | OIDC/SAML/passkeys = authn · escopos OAuth/RBAC/ACLs = authz |
| A divisão das falhas | AuthN falha como roubo de conta · AuthZ falha como escalação de privilégios |
Como autenticação e autorização rodam em uma requisição
1 POST /login (credenciais + MFA) ── AUTENTICAÇÃO, uma vez
← token de sessão / cookie: identidade estabelecida
2 GET /documents/xKd91m ── toda requisição dali em diante:
a · token validado → identidade restabelecida (mecanismo de authn)
b · permissão avaliada → ADA pode ler ESTE documento? (decisão de authz)
→ 200 os dois passaram
→ 401 token ausente/inválido — desafio WWW-Authenticate; fazer login resolve
→ 403 token ok, permissão negada — logar de novo não resolve nada
→ 404 algumas APIs escondem por completo os objetos proibidos (a RFC 9110 permite)
A mesma divisão em código de aplicação — faça login uma vez, seja julgado a cada operação:
// JavaScript / Node.js — Back4app JS SDK
// Authentication: once — who are you?
const user = await Parse.User.logIn('ada', password); // session token issued
// Authorization: every request — may YOU do THIS?
const doc = await new Parse.Query('Document').get('xKd91m');
// found if an ACL entry grants ada read · "not found" if not
doc.set('title', 'Renamed');
await doc.save(); // succeeds only if an entry grants ada WRITE // Flutter / Dart — Back4app Flutter SDK
// Authentication: once — who are you?
final user = ParseUser('ada', password, null);
await user.login(); // session token issued
// Authorization: every request — may YOU do THIS?
final response = await QueryBuilder<ParseObject>(ParseObject('Document'))
.query(); // returns only rows whose ACLs grant ada read
final doc = response.results!.first as ParseObject;
doc.set('title', 'Renamed');
await doc.save(); // succeeds only if an entry grants ada WRITE // iOS / Swift — Back4app Swift SDK
// Authentication: once — who are you?
let user = try await User.login(username: "ada", password: password)
// session token issued
// Authorization: every request — may YOU do THIS?
guard var doc = try await Document.query("objectId" == "xKd91m").first()
else { return } // found only if an ACL entry grants ada read
doc.title = "Renamed"
_ = try await doc.save() // succeeds only if an entry grants ada WRITE // Android / Kotlin — Back4app Android SDK
// Authentication: once — who are you?
val user = ParseUser.logIn("ada", password) // session token issued
// Authorization: every request — may YOU do THIS?
val doc = ParseQuery.getQuery<ParseObject>("Document").get("xKd91m")
// found if an ACL entry grants ada read · "not found" if not
doc.put("title", "Renamed")
doc.save() // succeeds only if an entry grants ada WRITE Autenticação vs. autorização, lado a lado
| Autenticação | Autorização | |
|---|---|---|
| Pergunta | Quem é você? | O que você pode fazer? |
| Entradas | Credenciais: senhas, códigos de MFA, passkeys, biometria | Políticas: papéis, ACLs, atributos, escopos |
| Frequência | Uma vez por session (+ step-up em ações sensíveis) | Toda requisição, todo objeto |
| Produz | Uma session ou um token | Uma decisão de permitir/negar |
| O usuário vê | Sim — a tela de login | Raramente — funciona de forma invisível |
| Onde roda | Na borda: camada de identidade, fluxo de login | No fundo: camada de negócio e de dados, ao lado dos dados |
| Protocolos | OpenID Connect, SAML, WebAuthn | Escopos OAuth 2.0, engines RBAC/ABAC/ReBAC |
| Token padrão | ID token — quem se autenticou | Access token — o que o portador pode fazer |
| Falha como | Roubo de conta | Escalação de privilégios, exposição de dados |
Duas linhas merecem suas notas de rodapé. Onde roda: a autenticação naturalmente se concentra na borda — um fluxo de login, um provedor de identidade — enquanto a autorização pertence ao lado dos dados que protege, porque “este usuário pode tocar neste objeto?” precisa do objeto. Falha como: os modelos de ameaça são disjuntos — credential stuffing e phishing atacam a autenticação (por isso MFA é a defesa de authn de maior alavancagem), enquanto broken object-level authorization lidera as listas de segurança de APIs como a falha de authz por excelência: usuário logado, objeto errado, ninguém verificou.
401 e 403, com precisão
Os códigos de status são a distinção vestindo números, e a RFC 9110 é exata sobre isso. 401 Unauthorized é um dos nomes errados mais duradouros da história: significa não autenticado — a requisição “não possui credenciais de autenticação válidas”, a resposta deve carregar um desafio WWW-Authenticate e apresentar credenciais pode resolver. 403 Forbidden significa que o servidor entendeu exatamente quem estava pedindo e recusa mesmo assim — reautenticar é inútil por definição. E a especificação abençoa um terceiro movimento que os times de segurança adoram: responder 404 em vez de 403, para que um recurso proibido não confirme a própria existência. Acertar os códigos não é pedantismo; os clientes constroem lógica de retry e de novo login sobre eles, e um 403 que deveria ser 401 manda o usuário contra uma parede em vez de um formulário de login.
OAuth, OIDC e a confusão eterna
A confusão tem uma resposta em forma de especificação. O título do OAuth 2.0 é “The OAuth 2.0 Authorization Framework” — ele movimenta permissões com escopo, e a especificação do OpenID Connect existe justamente porque o OAuth sozinho “é incapaz de fornecer informações sobre a autenticação de um usuário final”. O OIDC adiciona a camada de identidade: um ID token atestando quem se autenticou, distinto do access token que atesta o que o portador pode fazer. Todo botão de “Entrar com…” é o OIDC fazendo autenticação sobre o encanamento de autorização do OAuth — um fluxo, os dois conceitos, em camadas limpas em vez de confundidos.
Os três erros que vão para produção
Autorização no cliente. Esconder o botão de excluir é design de interface; o servidor decidir se a exclusão executa é segurança. Segundo a OWASP: negue por padrão, aplique no servidor e trate verificações no cliente como dicas de UX. Logado ≠ autorizado. Verificar a autenticação, mas não a posse do objeto — /documents/42 servido a qualquer session válida — é broken object-level authorization, a classe de vulnerabilidade mais comum em APIs. A verificação é por objeto, por requisição, sem exceções. Ordem dos middlewares. Autentique primeiro, autorize depois, no código como no conceito: o middleware de identidade estabelece quem, depois os handlers perguntam se pode — e uma verificação de autorização que roda antes de a identidade ser estabelecida autoriza silenciosamente o anônimo.
Casos de uso comuns
- Login no app + permissões de dados — o par do dia a dia: um fluxo de auth, regras por objeto em tudo que vem depois.
- Design de APIs — semântica de 401/403, tokens com escopo e verificações por objeto como a linguagem de erro do contrato.
- SaaS multi-tenant — autenticação compartilhada entre os tenants; autorização rigidamente confinada dentro de cada um.
- Ferramentas de admin e suporte — autenticação step-up e autorização elevada, deliberadamente como eventos separados.
- Conteúdo público + privado — leitura anônima como regra de autorização, provando que os dois conceitos rodam de forma independente.
Qual verificação está faltando? Matriz de decisão
| Sintoma | Peça faltante |
|---|---|
| Qualquer um com o link lê dados privados | Autorização — verificações por objeto |
| Senhas roubadas continuam funcionando | Autenticação — adicione MFA |
| Usuários veem paredes de 403 após erros de login | Código errado — isso é um fluxo de 401 |
| Qualquer usuário logado acessa APIs de admin | Autorização — papéis, negar por padrão |
| ”Entrar com…” tratado como autorização | Mistura de conceitos — OIDC autentica; escopos autorizam |
| Botões escondidos, mas endpoints abertos | Autorização aplicada só no cliente |
Limitações e trade-offs
- A divisão é conceitual, nem sempre arquitetural. Apps pequenos razoavelmente rodam as duas no mesmo stack de middleware; a disciplina é manter as verificações distintas, não os servidores.
- Authn forte não salva authz fraca. Passkeys e MFA verificam a identidade com perfeição para um sistema que depois deixa qualquer um ler qualquer coisa — as falhas são independentes.
- Autorização por requisição tem custo. Cachear decisões, empurrar regras para a camada de dados e indexar permissões é como “verificar tudo” continua rápido.
- Step-up borra a linha do tempo. Ações sensíveis reautenticam no meio da session — a autenticação não é estritamente “uma vez”, é “uma vez por nível de garantia”.
- Deriva de vocabulário causa bugs reais. Times que dizem “auth” para as duas metades escrevem tickets, testes e códigos de erro que as confundem; as palavras são a defesa mais barata.
Autenticação e autorização no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. A arquitetura da plataforma é a divisão: a classe User, as sessions, o login social e o adaptador de MFA respondem quem é você, produzindo um token de sessão revogável — e então as ACLs, as permissões em nível de classe e os papéis respondem o que você pode fazer, avaliados no servidor em toda requisição REST, GraphQL e Live Query — exatamente como as abas de código mostram: login uma vez, julgamento a cada operação. A seção dos erros vira estrutura: a autorização não pode ficar no cliente porque o Back4app a aplica atrás da API, objetos não autorizados voltam como não encontrados em vez de confirmar a própria existência, e negar por padrão é um checkbox em uma classe. As duas perguntas permanecem separadas porque a plataforma nunca deixa que elas se misturem.
Perguntas frequentes
Qual a diferença entre autenticação e autorização em termos simples?
Autenticação verifica quem você é — credenciais, códigos, biometria. Autorização decide o que você pode fazer — papéis, permissões, políticas. Na versão hotel: mostrar o documento na recepção é autenticação; o cartão que abre o seu quarto, mas não a cobertura, é autorização.
O que vem primeiro: autenticação ou autorização?
Autenticação, quase sempre — um sistema não consegue conceder permissões a uma parte desconhecida. A exceção instrutiva: recursos públicos são decisões de autorização tomadas sem autenticação; "qualquer um pode ler isto" continua sendo uma regra de permissão, aplicada ao anônimo.
Qual a diferença entre os erros 401 e 403?
401 significa que a requisição não tem credenciais de autenticação válidas — apesar do nome oficial "Unauthorized", ele quer dizer não autenticado, e fazer login pode resolver. 403 significa que o servidor sabe quem você é e recusa mesmo assim — permissão negada, e fazer login de novo não muda nada.
Pode existir autorização sem autenticação?
Sim — todo endpoint público é a prova: acesso anônimo é uma regra de autorização avaliada sem identidade. O inverso também existe: autenticado, mas sem autorização para nada — exatamente o que uma conta recém-criada, sem papéis atribuídos, deveria ser.
Quais protocolos cuidam da autenticação e quais da autorização?
Autenticação: senhas, MFA, passkeys e WebAuthn, sessions, OpenID Connect, SAML. Autorização: papéis (RBAC), regras por atributo (ABAC), ACLs, escopos do OAuth 2.0, engines de política. O OAuth fica famosamente no lado da autorização — sua fama de login vem do OpenID Connect rodando por cima dele.
OAuth é autenticação ou autorização?
Autorização — o título da própria especificação é "The OAuth 2.0 Authorization Framework", e a especificação do OpenID Connect existe justamente porque o OAuth sozinho não consegue atestar quem se autenticou. Todo botão real de "Entrar com…" é o OIDC adicionando uma camada de identidade sobre o encanamento do OAuth.
Como autenticação e autorização funcionam juntas em uma requisição?
Você se autentica uma vez no login, produzindo uma session ou um token. Depois, em cada requisição, o servidor restabelece a identidade a partir desse token e avalia a autorização para o recurso e a ação específicos. Uma vez por session versus toda requisição — essa assimetria é a arquitetura inteira.
Quais são os erros mais comuns?
Confundir os dois no tratamento de erros (403 onde deveria ser 401), aplicar autorização no cliente (esconder botões é UX, não segurança) e verificar que o usuário está logado, mas não que ele é dono do objeto específico — a falha de broken object-level authorization que lidera as listas de segurança de APIs.