Falaaaaaaaaaa desenvolvedor, tudo bem? Eu estou bem e no artigo de hoje vamos falar de um tema super importante para todo desenvolvedor web, a segurança de suas aplicações.
E como o assunto é segurança a gente não pode deixar de falar sobre autenticação e autorização. Na web uma das tecnologias mais utilizadas para essa questão de segurança é o JWT (JSON Web Tokens) e é sobre isso que vamos falar hoje.
…
Entendendo o JWT
Antes de sairmos escrevendo código por aí precisamos entender o que é o JWT e como ele funciona e antes de entender o JWT precisamos entender o que é autenticação, autorização e porque isso tudo é tão importante.
Vamos por partes, o que seria AUTENTICAÇÃO? Para entender isso vamos para uma simples analogia, quando você entra em um condomínio empresarial e lá eles pedem pra você se identificar com algum documento, seja ele RG ou CPF, fazendo isso você está autenticado, você provou para a recepção do condomínio (utilizando seu documento) que você é realmente você.
Beleza, mas então o que é AUTORIZAÇÃO afinal? Partindo da mesma analogia do condomínio empresarial, se você foi nesse condomínio certamente quer visitar alguma empresa e para isso não basta apenas estar autenticado, então você informa na recepção que quer visitar o localX, a atendente liga para o local perguntado se você realmente pode entrar e liberam seu acesso. Nesse processo a instituição que você queria visitar AUTORIZOU a sua entrada.
Beleza e porque isso é tão importante na hora de construirmos nossas API’s? Ora jovem desenvolvedor eu te respondo, a partir do momento que hospedamos nossa aplicação em algum servidor qualquer pessoa ou software que consiga fazer uma requisição utilizando o verbo requerido pela rota pode ter acesso aos nossos dados. E não queremos que nossos dados sejam acessados por qualquer pessoa não é mesmo?
Exato, somente as aplicações autorizadas podem ter acesso aos nossos dados e para isso temos uma tecnologia incrível para nos ajudar com isso, o JWT ou JSON WEB Tokens.
Agora que a gente entendeu um pouco do cenário onde aplicar, vamos adentrar realmente a parte de entender como funciona.
O JWT (JSON Web Tokens) é um padrão RFC 7519 utilizado para realizar autenticação e autorização entre duas partes por meio de tokens, esse token é assinado digitalmente portanto pode ser válido a qualquer momento.
Basicamente esse token é formado por três partes, Header, Payload e Signature.
No nosso Header, nós temos as informações sobre a composição do token, no caso JWT (typ) e qual algoritmo de criptografia ele irá utilizar (alg).
O Payload é um objeto que contém as informações do usuário autenticado.
E por fim temos a Signature, que é a junção do hash nosso Header e nosso Payload, ambos em base64 junto com uma chave secreta definida pelo usuário.
Essa assinatura serve para garantirmos a integridade e veracidade do nosso token, garante que realmente foi gerado pela sua aplicação e não é forjado.
Por fim temos um token contendo 3 partes (Header, Payload e Signature) separadas por um caractere coringa (o ponto final).
Entrando no site jwt.io podemos ver de forma prática a geração de um token, seguindo o exemplo.
Com isso conseguimos ter uma visão geral de como funciona um token JWT, recomendo que caso você tenha ficado meio confuso, entre no site oficial jwt.io e comece a criar seus tokens para melhor entendimento.
…
Mãos na Massa!
Agora que a gente já entendeu o funcionamento de uma forma geral do JWT vamos botar a mão no código e aplica isso para um cenário real.
O cenário é o seguinte: você necessita de uma API na qual para que suas rotas sejam consumidas quem irá realizar a requisição precisa ser um usuário autenticado e existente na base de dados, outro detalhe, cada usuário tem um tipo de cargo e cada cargo desse pode acessar somente algumas rotas específicas.
No nosso cenário temos 3 tipos de usuário, o colaborador, o gerente e por fim temos o diretor.
Diretor: Pode acessar todas as rotas e tem permissão para consumir todas as rotas.
Gerente: Pode acessar todas as rotas públicas, relacionadas a gerência e a colaboradores.
Colaborador: Pode consumir apenas rotas públicas relacionadas ao próprio.
Agora que já temos nosso cenário vamos criar nosso projeto, para isso vou utilizar o Visual Studio 2019 e o SDK do .NET Core 3.1.
Crie um projeto Web utilizando o template WebAPI do ASP .NET Core e bora para o código.
Com nosso projeto já criado deixa a estrutura da seguinte forma:
Vamos entender um pouco mais a divisão feita aqui:
Models: Fica nosso modelo de dados da entidade usuário que iremos utilizar.
Helpers: Lá irá ficar a nossa classe auxiliar que irá gerar o token para nós e autenticar o usuário.
Repositories: Uma classe servindo como repositório para simular a ida e o retorno de um usuário na base de dados.
Beleza agora que já está tudo estruturado a primeira coisa a se fazer é instalar o pacote:
Microsoft.AspNetCore.Authentication.JwtBearer
Agora com o pacote já instalado precisamos configurar o middleware do JWT na nossa aplicação.
Para isso vá no arquivo Startup.cs e no método ConfigureServices adicione o seguinte código:
Aqui passamos nossa chave secreta para a configuração do middleware, assim, conseguimos validar se o token foi gerado pela própria aplicação.
Por fim, no mesmo arquivo e no método Configure, adicione:
app.UseAuthentication();
app.UseAuthorization();
O segundo passo é definir nosso modelo de entidade de usuário na aplicação, então em User.cs insira esse código:
Beleza, agora a gente precisa da nossa classe repositório, ela vai simular a ida e a consulta no banco de dados e vai trazer o usuário pra gente na hora do login.
Em UserRepository.cs adicione o seguinte código:
Beleza, agora vem a parte mais importante, que é a classe auxiliar que vai gerar e escrever o token, essa eu vou explicar detalhadamente seu funcionamento.
Na classe JwtAuth.cs adicione o seguinte código:
Para gerar o token, precisamos de uma classe estática e de uma função estática, afinal sempre irá realizar a mesma coisa e não se precisa de instância.
Criamos uma instância do token handler do JWT (quem vai criar e escrever os tokens).
Fizemos um vetor de bytes através da chave secreta (necessário para a criptografia).
Depois criamos nosso Payload com as informações do usuário logado (Subject), setamos o tempo de duração do token (Expires) e por fim definimos qual algoritmo iremos utilizar no Header (SigningCredentials).
Perceba que em Subjects, onde defino as propriedades do usuário, tem uma Claim chamada Role, na qual eu chamo uma mini factory que de acordo com o tipo do usuário (Type) me retorna qual nível de permissão dele.
OBS: Factory é um padrão de projeto muito utilizado, caso você não conheça, recomendo esse artigo.
https://refactoring.guru/pt-br/design-patterns/factory-method/csharp/example
Por fim criamos e assinamos digitalmente o nosso token, a partir daí ele está válido e quem tiver pode acessar as nossas rotas dependendo de seu nível de permissão.
Perfeito, agora toda nossa parte do JWT está implementada e funcionando, agora só precisamos fazer as rotas que serão consumidas.
Vamos lá, a primeira rota que a gente precisa é uma rota pública na qual o usuário poderá se autenticar (realizar o login) e caso seja um usuário válido irá receber seu token.
No arquivo AuthController.cs digite o seguinte código:
Uma rota assíncrona que recebe através do Body da requisição um JSON com os dados do login do usuário, caso seja um usuário válido chama o auxiliar de criação do token, senão retorna somente uma mensagem para o usuário.
Por fim as rotas protegidas por token e protegidas por permissão.
No arquivo UserController.cs digite o seguinte código:
Na rota que tem somente [Authorize] pode ser acessada por qualquer usuário desde que ele esteja autenticado.
Agora nas rotas que tem [Authorize(Role=”...”)] além de estar autenticado o usuário precisa ter a Role indicada, ou seja, se um usuário com permissão de colaborador, tentar acessar uma rota na qual só permite diretores o acesso a essa rota será negado.
…
Referências e auxiliares
Para poder escrever esse conteúdo eu utilizei alguns links auxiliares e algumas referências e vou deixar logo abaixo, recomendo que para um melhor entendimento de uma lida nesses conteúdos feras!!!
https://blog.codeexpertslearning.com.br/conhecendo-o-jwt-114afbfcad95
https://medium.com/tableless/entendendo-tokens-jwt-json-web-token-413c6d1397f6
https://tools.ietf.org/html/rfc7519
https://fgodoy.me/2016/05/jwt-hole/
https://balta.io/blog/aspnetcore-3-autenticacao-autorizacao-bearer-jwt
…
Conclusão
No artigo de hoje eu demonstrei o que é, como funciona e como utilizar o JWT junto com esquema de Roles no ASP .NET Core 3.1, além disso tentei passar um pouco da importância de se ter uma boa segurança em nossas API’s espero que tenha ficado claro e objetivo o artigo.
Agradeço a atenção e bons estudos!!!!!
Caso precise entrar em contato, me mande uma mensagem aqui.
Baixe o projeto clicando aqui.