.NET - JWT x OAuth


 Hoje vamos fazer uma comparação entre dois conceitos relacionados à autenticação e autorização muito usados em aplicações web : o padrão JWT e o protocolo OAuth.

O JWT é um padrão aberto (RFC 7519) para criar tokens de acesso que são usados para autenticar e autorizar solicitações entre as partes.

O JWT é geralmente usado para autenticação stateless, o que significa que não há necessidade de armazenar informações do usuário no lado do servidor sendo que um token JWT é uma string compacta que consiste em três partes separadas por pontos: o cabeçalho (header), a carga útil (payload) e a assinatura.

O cabeçalho especifica o algoritmo de criptografia usado para assinar o token, a carga útil contém as informações do usuário (como ID, nome, papéis) e a assinatura garante a integridade do token. O token JWT é enviado pelo cliente em cada solicitação para autenticar-se no servidor.

As principais vantagens da autenticação JWT são:

OAuth

Já o OAuth , é um protocolo de autorização que permite que um aplicativo acesse recursos protegidos em nome do usuário, sem precisar saber as credenciais de login do usuário sendo frequentemente usado para permitir que aplicativos de terceiros acessem APIs (interfaces de programação de aplicativos) de serviços populares, como redes sociais, sem compartilhar senhas reais.

O fluxo básico do OAuth envolve três partes:

  1. O provedor de serviço (como uma rede social),

  2. O aplicativo cliente (que deseja acessar recursos do usuário)

  3. O usuário final.

O usuário fornece consentimento ao aplicativo cliente para acessar seus recursos protegidos, e o provedor de serviço emite um token de acesso ao aplicativo cliente, que é usado para autenticar e autorizar solicitações subsequentes.

As principais vantagens do OAuth 2.0 são:

A principal diferença entre JWT e OAuth é que o JWT é um formato de token para autenticação, enquanto o OAuth é um protocolo para autorização.

O JWT é usado para verificar a identidade do usuário e inclui informações sobre o usuário no token, permitindo que os recursos sejam acessados com base nessas informações.

O OAuth, por sua vez, permite que um aplicativo acesse recursos protegidos em nome do usuário, usando tokens de acesso emitidos por um provedor de serviço, sem compartilhar as credenciais do usuário.

JWT - Implementação

Para implementar a autenticação JWT no .NET 7, precisamos seguir o seguinte roteiro :

1- instalar o pacote Microsoft.AspNetCore.Authentication.JwtBearer

2- Definir a chave secreta (SecretKey), o emisso(Issuer) e o destino(Audience)  no arquivo appsettings.json

3- Adicionar o seguinte código na classe Program:

builder.services.AddAuthentication(options =>
{
  options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
 .AddJwtBearer(options =>
 {
   options.TokenValidationParameters =
new TokenValidationParameters
   {
     ValidateIssuer =
true,
     ValidateAudience =
true,
     ValidateLifetime =
true,
     ValidateIssuerSigningKey =
true,
    ValidIssuer = Configuration[
"Jwt:Issuer"],
    ValidAudience = Configuration[
"Jwt:Audience"],
    IssuerSigningKey =
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]   ))
 };
});
 

4- Na autenticação do usuário gerar o Token usando uma chave simétrica ou assimétrica usando  pacote System.IdentityModel.Tokens.Jwt :

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;

public class Program
{
    public static void Main(string[] args)
    {
        // Define a chave simétrica
        string chaveSimetrica = "chave_secreta";

        // Define as informações do usuário
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, "usuario_id"),
            new Claim("custom_claim", "valor_customizado")
        };

        // Gera o token JWT
        var tokenHandler = new JwtSecurityTokenHandler();
        var chave = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(chaveSimetrica));
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.UtcNow.AddHours(1),
            SigningCredentials = new SigningCredentials(chave, SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        var tokenString = tokenHandler.WriteToken(token);

        // Exibe o token JWT gerado
        Console.WriteLine(tokenString);
    }
}

5- Configuração do roteamento e autenticação nas rotas

app.UseAuthentication(); // Aplicar autenticação
app.UseAuthorization();
// Aplicar autorização

6- Proteger as rotas

Agora, você pode proteger as rotas específicas que deseja exigir autenticação usando o atributo
[Authorize(AuthenticationSchemes = "Bearer")] no controlador ou em métodos Actions específicos do controlador.

OAuth - Implementação

Para implementar o OAuth 2.0 no .NET 7 podemos seguir o seguinte roteiro simplificado:

1- Instalar o pacote Microsoft.AspNetCore.Authentication.OAuth

2- Configurar a autenticação OAuth 2.0 na classe Program:

builder.Services.AddAuthentication(options =>
{
   options.DefaultAuthenticateScheme =
"OAuth";
   options.DefaultChallengeScheme =
"OAuth";
})
  .AddOAuth(
"OAuth", options =>
  {
    options.ClientId =
"seu_client_id";
    options.ClientSecret =
"seu_client_secret";
    options.CallbackPath =
"/oauth/callback";
    options.AuthorizationEndpoint =
"URL_do_endpoint_de_autorizacao";
    options.TokenEndpoint =
"URL_do_endpoint_de_token";
    options.SaveTokens =
true;
   
// Configurações adicionais específicas do provedor OAuth
});
 

Substitua "seu_client_id", "seu_client_secret", "URL_do_endpoint_de_autorizacao" e "URL_do_endpoint_de_token" pelos valores correspondentes.

Além disso, você precisará fornecer as configurações adicionais específicas do provedor OAuth que você está usando. Consulte a documentação do provedor OAuth específico para obter informações sobre como configurar essas opções.

3- Configuração do roteamento e autenticação nas rotas

app.UseAuthentication(); // Aplicar autenticação
app.UseAuthorization();
// Aplicar autorização

4- Proteger as rotas

Agora, você pode proteger as rotas específicas que deseja exigir autenticação usando o atributo [Authorize] no controlador ou em métodos Actions específicos do controlador.

Comparação : JWT vs. OAuth  

Para facilitar a compreensão das diferenças entre JWT e OAuth, apresento a seguinte tabela comparativa:

Quando usar cada um

A escolha entre JWT e OAuth depende do seu caso de uso específico:

JWT: Use JWT quando você precisa autenticar um usuário e as informações do usuário precisam estar disponíveis para o servidor de recursos. JWT é ideal para APIs RESTful e SPAs, onde o servidor precisa verificar a identidade do usuário e conceder acesso a recursos com base nas informações contidas no token.

OAuth: Use OAuth quando você precisa conceder acesso a recursos protegidos em nome de um usuário, sem compartilhar as credenciais do usuário com o aplicativo cliente. OAuth é ideal para login social, onde um aplicativo de terceiros precisa acessar informações do usuário em um provedor de identidade (como Google ou Facebook).

Combinação de Ambos: Em alguns casos, você pode usar JWT e OAuth juntos. Por exemplo, um aplicativo cliente pode usar OAuth para obter um token de acesso de um provedor de identidade e, em seguida, usar esse token para solicitar um token JWT de um servidor de recursos. O token JWT pode ser usado para autenticar o usuário e autorizar o acesso a recursos específicos.

Conclusão

Concluindo, podemos dizer que tanto a autenticação JWT quanto o OAuth 2.0 são mecanismos de autenticação seguros e confiáveis que podem ser implementados em um aplicativo .NET 7. A autenticação JWT é adequada para autenticação sem estado, enquanto o OAuth 2.0 é mais adequado para autorização.

Compreendendo as diferenças entre os dois mecanismos e suas vantagens, você pode escolher o mecanismo de autenticação correto para seus aplicativos.

E estamos conversados.

"Porque Deus nos escolheu nele antes da criação do mundo, para sermos santos e irrepreensíveis em sua presença"
Efésios 1:4

Referências:


José Carlos Macoratti