Autenticação e autorização: dois conceitos que todo mundo confunde (e não deveria)
Autenticação é provar quem você é; autorização é decidir o que você pode. Confundir os dois é a origem de metade das falhas de segurança. Um guia de conceitos que duram.
Neste artigo
Duas palavras parecidas, abreviadas de forma quase idêntica — authn e authz —, guardam uma das distinções mais importantes e mais atropeladas da construção de software. Autenticação responde "quem é você?". Autorização responde "o que você tem permissão de fazer?". Parecem a mesma coisa porque quase sempre aparecem juntas, uma logo depois da outra, mas são etapas separadas, com mecanismos separados, e tratá-las como uma coisa só é a raiz de uma fração enorme das brechas de segurança que aparecem em auditorias.
O motivo de valer a pena entender isso a fundo, mesmo que você use uma biblioteca pronta que cuida dos detalhes, é que a lógica de quem pode o quê é específica do seu negócio e ninguém vai escrevê-la por você. A biblioteca valida a senha e emite o token; a decisão de que um usuário do plano gratuito não pode exportar relatórios, ou de que um membro de uma empresa não pode ver os dados de outra, é sua. Errar essa parte não gera um erro visível — gera um sistema que funciona perfeitamente até o dia em que alguém acessa o que não deveria. Este artigo separa os dois conceitos com calma e aponta os princípios que os mantêm corretos ao longo do tempo, independentemente de linguagem ou framework.
Quem você é versus o que você pode#
A melhor imagem para fixar a diferença é a de entrar em um prédio corporativo. Na portaria, você mostra um documento e prova que é quem diz ser — isso é autenticação. Lá dentro, seu crachá abre algumas portas e recusa outras: você entra no seu andar, mas não na sala do servidor nem no financeiro — isso é autorização. Provar a identidade não dá acesso a tudo; apenas estabelece quem está pedindo, para que a segunda pergunta, sobre permissões, possa ser respondida.
A ordem importa e é sempre a mesma. Primeiro se autentica, depois se autoriza. Não dá para decidir o que alguém pode fazer sem antes saber quem é. Mas o inverso também é verdadeiro e frequentemente esquecido: estar autenticado não implica estar autorizado. Um usuário logado é um usuário conhecido, não um usuário com carta branca. Todo endpoint precisa fazer as duas perguntas, e a resposta "sim" para a primeira nunca é resposta para a segunda.
Confundi-las gera dois tipos opostos de falha. Tratar autenticação como se fosse autorização produz sistemas onde qualquer usuário logado acessa qualquer recurso — o clássico "mas ele estava autenticado!" que precede um vazamento de dados. Tratar autorização como se fosse autenticação produz o contrário: checagens de permissão espalhadas que reimplementam identidade de forma inconsistente. Manter os dois conceitos nítidos na cabeça, e no código, evita as duas armadilhas.
Autenticação: provando identidade#
Autenticar é estabelecer, com confiança razoável, que quem faz o pedido é quem afirma ser. A força dessa prova depende de quantos e quais fatores independentes são exigidos.
Os fatores caem em três categorias. Algo que você sabe (uma senha, um PIN), algo que você tem (o celular, uma chave física, um token) e algo que você é (impressão digital, rosto). Cada categoria falha de um jeito diferente: senha vaza ou é adivinhada, dispositivo é roubado, biometria não pode ser trocada depois de comprometida. A força de um esquema de autenticação vem de combinar categorias, não de reforçar uma só.
A senha sozinha é o fator mais fraco. Ela é reutilizada entre sites, aparece em vazamentos, é vítima de phishing e de força bruta. Isso não a torna inútil, mas a torna insuficiente como única barreira para qualquer coisa que importe. Quando a senha é usada, ela precisa ser guardada com um algoritmo de hash lento e salgado — bcrypt, scrypt, argon2id —, jamais em texto puro nem com hashes rápidos como MD5 ou SHA simples, que um atacante reverte em massa.
Múltiplos fatores (MFA) é o piso para o que tem valor. Exigir um segundo fator — um código temporário, uma chave de segurança, uma passkey — significa que roubar só a senha não basta. É a diferença entre uma fechadura e uma fechadura com tranca. Entre as opções, as baseadas em criptografia de chave pública, como passkeys e WebAuthn, resistem a phishing por design, porque não há segredo digitável para o usuário ser enganado a entregar. Um detalhe conceitual importante: a identidade de uma pessoa não deveria ser o e-mail, que muda e se repete, e sim um identificador interno estável, ao qual e-mails e telefones se associam como formas de contato e recuperação.
Como a identidade viaja: sessão ou token#
Autenticar uma vez a cada requisição seria inviável — ninguém digita a senha a cada clique. Depois do login, o sistema precisa de uma forma de lembrar quem é o usuário nas próximas chamadas. Há duas abordagens conceituais.
Sessão no servidor: o servidor guarda o estado. No login, o servidor cria um registro de sessão e devolve ao navegador um identificador opaco, normalmente num cookie. A cada requisição, o cookie chega junto, o servidor procura a sessão correspondente e sabe quem está falando. A vantagem é o controle total: revogar uma sessão é apagar o registro, e o usuário é desconectado na hora. O custo é que o servidor precisa manter e consultar esse estado.
Token autocontido: a prova viaja com o pedido. Em vez de guardar o estado, o servidor emite um token assinado — um JWT é o exemplo mais comum — que carrega os dados de identidade dentro de si, protegidos por uma assinatura que o servidor sabe verificar. A cada requisição, o token vem junto e o servidor confirma a assinatura sem consultar um banco de sessões. Escala bem e funciona entre serviços, mas tem uma fraqueza conhecida: como o token vale sozinho até expirar, revogá-lo antes da hora é difícil, o que se resolve com tokens de vida curta somados a um mecanismo de renovação que pode ser revogado.
Onde a prova é guardada no cliente é uma decisão de segurança. Tokens e identificadores de sessão devem morar em cookies marcados como HttpOnly, Secure e SameSite, nunca no localStorage. A razão é direta: qualquer script que rode na página lê o localStorage, então uma única falha de XSS entrega a credencial inteira ao atacante. O cookie HttpOnly é invisível ao JavaScript, cortando essa via.
Autorização: o que fazer com a identidade#
Sabendo quem é o usuário, a autorização decide o que ele pode ver e fazer. Existem modelos de granularidade crescente, e escolher o certo depende de quão complexas são as regras do seu domínio.
ACL — lista de controle de acesso. A forma mais direta: cada recurso carrega uma lista de quem pode acessá-lo e como. Funciona bem quando as permissões são poucas e específicas por objeto, mas vira um pesadelo de manutenção quando o número de usuários e recursos cresce, porque não há abstração — cada permissão é declarada individualmente.
RBAC — controle baseado em papéis. Em vez de dar permissões a pessoas, você as agrupa em papéis — administrador, editor, leitor — e atribui papéis aos usuários. É o modelo mais usado porque casa com a forma como organizações pensam ("essa pessoa é gerente") e reduz drasticamente o número de decisões individuais. A limitação aparece quando as regras dependem de contexto além do papel.
ABAC — controle baseado em atributos. Aqui a decisão considera atributos do usuário, do recurso e do ambiente: "um gerente pode aprovar despesas do seu próprio departamento e abaixo de um limite". É muito mais expressivo que papéis fixos, ao custo de regras mais complexas de escrever e auditar.
ReBAC — controle baseado em relações. O modelo que responde perguntas do tipo "esse usuário é dono deste documento?" ou "ele pertence à equipe que tem acesso a esta pasta?". A autorização se torna uma consulta sobre um grafo de relações entre entidades. É o que melhor modela sistemas multi-inquilino e compartilhamento granular, onde o acesso depende de como as coisas se conectam, não de um papel global.
Princípios que não falham: menor privilégio e negar por padrão#
Independentemente do modelo escolhido, dois princípios sustentam qualquer esquema de autorização saudável, e violá-los é a origem da maioria das brechas.
Menor privilégio: só o necessário, nada além. Cada usuário, cada serviço, cada token deve ter exatamente as permissões que precisa para sua função, e nenhuma a mais. Um serviço que só lê um relatório não deveria ter permissão de apagar registros; um usuário que só edita o próprio perfil não deveria alcançar o de outros. Quanto menor o privilégio concedido, menor o estrago quando uma credencial é comprometida — e alguma credencial sempre acaba comprometida.
Negar por padrão: o silêncio significa não. A postura correta é começar negando tudo e liberar explicitamente o que é permitido, jamais o contrário. Um sistema que permite por padrão e tenta bloquear exceções vai, mais cedo ou mais tarde, esquecer de bloquear uma — e uma rota nova nasce aberta sem ninguém decidir isso. Com negar-por-padrão, o pior caso de um esquecimento é um acesso negado a quem deveria ter, um incômodo visível e corrigível, e não um vazamento silencioso.
Por que a decisão mora no servidor#
O erro conceitual mais comum e mais perigoso em autorização é confiar no cliente. Vale insistir nele porque é sedutor e recorrente.
Esconder um botão é experiência, não segurança. Um if (usuario.isAdmin) no front que oculta a opção de excluir melhora a interface, mas não protege nada: qualquer pessoa pode abrir as ferramentas de desenvolvedor, ver a chamada que o botão faria e disparar a requisição diretamente. Se a rota do servidor não reverifica a permissão, o controle todo era teatro. A regra é absoluta: o cliente pode refletir uma decisão de autorização, mas quem decide é sempre o servidor.
Identidade e escopo vêm do token verificado, nunca do pedido. Um erro clássico é aceitar o identificador do usuário, o papel ou o inquilino a partir do corpo ou da query da requisição — dados que o cliente controla e pode forjar. O servidor deve extrair essas informações do token que ele mesmo validou, não do que o cliente afirma ser. Aceitar um user_id do corpo é convidar qualquer um a agir em nome de qualquer outro.
Todo acesso por identificador precisa checar a posse. A falha conhecida como IDOR acontece quando uma rota como /pedidos/1042 devolve o pedido só porque ele existe, sem verificar se ele pertence a quem pediu. Trocar o número na URL vira uma porta para os dados alheios. A correção conceitual é sempre a mesma: além de autenticar, confirmar que aquele usuário tem relação com aquele recurso específico, em toda rota que aceita um identificador.
Fechando#
Autenticação e autorização são duas perguntas distintas — quem é você, e o que você pode — e todo sistema seguro responde as duas, na ordem, sem confundir uma com a outra. Prove identidade com mais de um fator e guarde a credencial onde script nenhum a alcance. Decida permissões com o modelo que melhor descreve o seu domínio, sempre concedendo o mínimo e negando por padrão. E, acima de tudo, mantenha a decisão no servidor, extraindo identidade e escopo do token que você validou, jamais do que o cliente diz. Segurança de acesso raramente falha por criptografia fraca; falha porque alguém tratou "está logado" como se fosse "pode fazer isso". Manter essas duas frases separadas na cabeça é metade do trabalho.