Um dos grandes desafios em termos de aplicações web é garantir que quem esteja utilizando a aplicação tenha acesso às funções que em teoria são designadas para ele. Para isso, dois processos são envolvidos: Autenticação e Autorização.
A autenticação é o processo no qual é identificado o usuário que está utilizando a aplicação (através de diferentes possíveis métodos: usuário / senha, hash de autenticação / digest, certificados, integração com outros serviços de identidade, etc).
A autorização é o processo no qual é verificado se o usuário (já identificado anteriormente pelo processo de autenticação) tem acesso à função / informação solicitada. Isso pode ser baseado em ACLs (Access Control Lists / Listas de Controle de Acesso), perfis, flags (variáveis booleanas associadas diretamente ao usuário), dentre outras formas.
Nesse artigo, iremos abordar, em um nível conceitual (sempre com links de referência), como funciona a autenticação e a autorização.
Autenticação
Diversas formas de autenticação existem hoje, ainda mais com tantos serviços na nuvem. Vamos abordar, como de praxe, seguindo uma linha cronológica, explicando a evolução dos sistemas de autenticação.
Imagine um programa nativo. A forma mais simples de autenticação que podemos pensar é no código-fonte programa, estar programada uma senha (ou uma lista de possíveis senhas), e quando o usuário abre a aplicação, a primeira coisa que pergunta é a senha. Então o usuário digita a senha, e se a senha bate com uma das que foram programadas, o programa identifica a senha que foi digitada, atribuindo a sessão do usuário a um perfil, que posteriormente pode ser utilizado no processo de autorização. Infelizmente, esse não é um processo muito seguro de autenticação, uma vez que é muito sujeito a ataques (uma pessoa que deseja descobrir a senha pode construir um outro programa que automaticamente abre o programa e testa uma senha, e através de uma lista de senhas ou um gerador de senhas, pode ficar tentando aleatoriamente abrir o programa). Esse tipo de ataque é chamado de força bruta, e é muito comum.
Para reforçar um pouco mais a autenticação, podemos pensar em pedir duas informações ao usuário: o ID de usuário (user id) e a senha. Dessa forma, ao entrar essas informações, o programa primeiro testa se o ID de usuário existe, e caso exista, testa sua senha. Caso alguma dessas validações falhe, o programa pode retornar um erro genérico de autenticação, dificultando um pouco mais tentativas de quebrar a proteção através de força bruta. Isso não inviabiliza o ataque, porém o torna mais difícil.
Em vez de os dados de autenticação estarem dentro do programa, podemos pensar em deixá-los em uma fonte externa (banco de dados ou arquivo – se for, melhor criptografado). Ou ainda, podemos utilizar sistemas de autenticação especializados, como um servidor LDAP, Kerberos, ou outro serviço dessa forma.
Autenticação na Web
HTTP Basic Authentication
A autenticação básica HTTP é uma forma de autenticar no servidor onde, na requisição, mais precisamente no cabeçalho, é adicionado um campo chamado Authorization. O valor desse campo deve ser então “Basic “, onde é a representação Base64 da string :. A representação Base64 é uma forma de serializar essa string.
Cookies e Tokens
O protocolo HTTP permite a utilização de Cookies. Cookies são dados armazenados no lado cliente, mas acessíveis pelo servidor. Esse, na verdade, não é um método de autenticação exatamente, mas apenas um meio. Utilizando o dado que está em um determinado cookie, o servidor pode realizar a autenticação de otura forma. Em vez de o dado estar em cookies, também pode ser enviado como um cabeçalho. Algumas aplicações trabalham com o conceito de Token, que é uma string identificadora de credencial, que permite login. Através dessa string, o sistema é capaz de realizar a autenticação. Muitas APIs Web, como por exemplo, as APIs do Google (Google Maps, Google Fonts, etc), hoje utilizam Tokens como método de acesso, em que quando o desenvolvedor deseja utilizar, deve criar um token na ferramenta deAutorização administração, e para a aplicação utilizar a API, deve passar o token como um parâmetro ou cabeçalho, de forma que a API identifique a aplicação que está realizando a chamada.
Senhas Voláteis (One-Time Passwords)
A aplicação também pode utilizar um algoritmo de OTP (One-Time Password), seja baseado em algoritmo temporal, ou com acesso a base de chaves OTP. Dessa forma, a idéia é que a cada chamada, seja enviada uma senha diferente. Um exemplo disso faz uso de dispositivos físicos que geram uma nova numeração de tempos em tempos, muito utilizado por bancos.
Certificados de Usuário
Utilizando-se de métodos de criptografia, é possível a criação de um sistema de chaves públicas e privadas, que são bem seguros. Dessa forma, para acessar um sistema, o usuário deve possuir suas chaves públicas e privada, e o servidor, deve ter posse de sua chave pública. As chaves funcionam da seguinte forma: a chave pública é capaz de criptografar uma mensagem, e apenas a chave privada é capaz de descriptografar a mensagem que foi criptografada através da chave pública correspondente. Uma referência que explica bem detalhadamente como funciona encontra-se em https://www.lambda3.com.br/2012/12/entendendo-de-verdade-a-criptografia-rsa/. Não é o objetivo deste artigo explicar detalhadamente como funciona o método, uma vez que existem já bibliotecas que o implementam, portanto, caso o leitor queira saber mais em detalhes como funciona, pode ler a referência, e ainda acessar a especificação RFC 3447. Os certificados de usuário podem ser utilizados diretamente como identidades na sessão Web, ou podem ser mapeados para um usuário de rede (por exemplo, no servidor Web da Microsoft, através de IIS Client Certificate Mapping ou de Active Directory Client Certificate Mapping), que converte (impersonaliza) a identidade da sessão Web, e muda o tipo de autenticação após ter realizado a primeira autenticação, via certificados. O mapeamento é configurado no servidor, e mapeia um certificado (chave pública) em uma credencial de rede (usuário e senha). No fundo, o servidor web, se assim configurado, ao identificar uma autenticação por certificado, procura pelo mapeamento, e caso exista, realiza um novo login, dentro do mesmo processo, a fim de trocar o a identidade (no caso credencial Windows) daquele processo, e após isso ser realizado, pode acessar qualquer função dentro do servidor acessível por aquela credencial mapeada, como por exemplo, acessar uma base de dados também com Windows Authentication, ou abrir qualquer outra sessão em sistemas dessa forma (Windows Authentication).
Certificados de Servidor
Hoje, é bem comum, eu diria até obrigatória, a utilização de certificados também no lado do servidor, para autenticá-lo. Conhecemos isso hoje por HTTPS. Dessa forma, o usuário pode ter mais segurança de que está acessando o servidor correto, e não algum interceptador (man-in-the-middle) não autorizado, um ataque muito comum.
Autenticação Windows / Kerberos
A Microsoft implementou uma variante do sistema Kerberos de autenticação, que hoje funciona como método padrão de autenticação em ambientes Microsoft, e também está disponível em seu servidor web (Internet Information Services). Em um ambiente homogêneo Microsoft, é bem simples utilizar a autenticação Windows, uma vez que todos os seus sistemas (servidor web / IIS, servidor de banco de dados / SQL Server, RPC, dentre outros) suportam autenticação Windows (variante da Kerberos originalmente concebida).
Autenticações em Nuvem
Hoje, existem serviços na Web de identidade, que podem manter a parte de autenticação, como implementações do protocolo OAuth, dentre outros. Bons exemplos disso que são amplamente utilizados hoje é a autenticação Google e a autenticação Facebook, que diversos sites hoje fazem uso, permitindo que o perfil do usuário seja diretamente integrado à identidade Google / Facebook que ele possui.
Autorização
Após ser realizada a autenticação, nos certificamos de que o usuário que está acessando a aplicação é realmente um usuário designado para acessá-la, e mais, temos informações suficientes para saber quem (em termos de perfil) está utilizando, dessa forma, podemos dar acesso a partes da aplicação para determinado usuário, a outras partes, para outro usuário. Essa checagem pode ser feita de diversas formas, que um dia, abordaremos fora dessa série de artigos, mas são principalmente, ACLs (Listas de Controle de Acesso / Access Control Lists), RBAC (Perfis – por exemplo: Administrador, Gerente, Supervisor, etc / Role Based Access Control), Escopos de Tokens. Não abordaremos aqui por se tratar de métodos que requerem mais detalhamento em sua implementação técnica, o que não é escopo desse artigo. Dessa forma, esse parágrafo é suficiente, para que se entenda superficialmente o conceito.
Ok! Nos vemos no próximo artigo! Esperamos que o leitor esteja gostando da série, e na próxima, falaremos sobre arquitetura de aplicações web (Infraestrutura, função e dados), incluindo padrões amplamente utilizados, como MVC (Model-View-Controller), MVW (Model-View-Whatever), ORMs (Object-Relational Mapper), DBAL (DataBase Abstraction Layer), dentre outros.
Até mais!
Pedro Ferreira