O JWT Bearer Manual e o Bearer Token nativo da ASP.NET Core
   Você sabe a diferença entre o JWT Bearer manual e o Bearer Token nativo da ASP.NET Core ?

A partir do .NET 8, a Microsoft introduziu uma nova forma de autenticação baseada no ASP.NET Core Identity, o que gerou bastante confusão. Hoje podemos identificar duas abordagens distintas para autenticação com Bearer Token.

O ponto principal é entender que ambas utilizam o esquema Bearer, mas não geram o mesmo tipo de token nem utilizam a mesma infraestrutura.
 
 

O1. JWT Bearer "Manual" (tradicional)

Esta é a abordagem utilizada desde o ASP.NET Core 2.x e continua sendo a mais comum em APIs públicas. Nela, o ciclo de vida do token (criação, definição de declarações/claims, assinatura e expiração) é controlado programmaticamente pela própria aplicação, sem delegar a emissão a um servidor de identidade externo (como IdentityServer, Keycloak ou Azure AD).

Como Funciona a Emissão

O fluxo baseia-se em um serviço dedicado da aplicação (geralmente um TokenService) que intercepta requisições de login válidas e constrói a string JWT codificada:

Definição de Claims (ClaimsIdentity): Mapeamento do identificador do usuário, e-mail, funções (roles) e permissões customizadas no payload.

Assinatura Digital (SigningCredentials): Uso de uma chave secreta simétrica (SymmetricSecurityKey) com algoritmos como HMAC-SHA256 (SecurityAlgorithms.HmacSha256Signature) para garantir a integridade do token.

Serialização e Emissão: Utilização de instâncias como JwtSecurityTokenHandler (ou o JsonWebTokenHandler, otimizado para performance no .NET 8+) para assinar e serializar o token em sua representação string no padrão header.payload.signature.

Principais Componentes e Configuração:  
// Exemplo conceitual da construção do token em C#
var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(new[] 
    {
        new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
        new Claim(ClaimTypes.Email, user.Email),
        new Claim(ClaimTypes.Role, user.Role)
    }),
    Expires = DateTime.UtcNow.AddHours(2),
    Issuer = builder.Configuration["Jwt:Issuer"],
    Audience = builder.Configuration["Jwt:Audience"],
    SigningCredentials = new SigningCredentials(
        new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)), 
        SecurityAlgorithms.HmacSha256Signature)
};
var handler = new JwtSecurityTokenHandler();
var token = handler.CreateToken(tokenDescriptor);
var jwtString = handler.WriteToken(token);

Depois a API valida esse JWT:
builder.Services
     .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
     .AddJwtBearer(options =>
     {
          options.TokenValidationParameters = ...
     });

Quando Utilizar

Em APIs Standalone ou Microserviços Leves: Quando a aplicação não exige arquitetura SSO (Single Sign-On) nem múltiplos clientes consumindo a mesma base de autenticação.

Para controle Total da Lógica de Negócio: Aplicações com fluxos customizados de refresh token, revogação manual via banco de dados ou schemas de claims dinâmicos.

Em projetos sem Provedores de Identidade Externa: Cenários onde não há infraestrutura para manter uma instância dedicada de Identity Provider (IDP).

No nível da API (HTTP/ASP.NET Core) para padronizar a resposta de erro enviada ao cliente.

2. Bearer Token Nativo do ASP.NET Core Identity (.NET 8+)

Introduzido no .NET 8 com a API de Identity Endpoints (MapIdentityApi<TUser>()), o ASP.NET Core passou a fornecer um mecanismo embutido de Bearer Tokens nativos.

Diferente do JWT tradicional, essa abordagem não gera um JWT padrão por padrão, mas sim um token opaco (opaque token) criptografado e assinado pela própria infraestrutura de proteção de dados do framework (DataProtection).

Como Funciona a Emissão Nativa

Ao mapear os endpoints nativos do Identity via builder.Services.AddAuthentication().AddBearerToken(), a infraestrutura expõe rotas prontas como /login e /refresh:

1- Geração Sem JWT: Quando o usuário envia credenciais válidas para /login, o middleware do Identity compõe a identidade (ClaimsPrincipal) e a serializa em uma string criptografada e protegida pela chave do DataProtection.

2- Payload Protegido: O token emitido é opaco para o cliente (uma string ilegível que não pode ser decodificada em sites como jwt.io), garantindo que o cliente apenas armazene e repasse o token sem inspecionar suas claims.

3- Gestão Transparente de Refresh Token: A resposta traz automaticamente um accessToken e um refreshToken, reduzindo a necessidade de criar tabelas e serviços manuais de renovação de sessão.

Exemplo de Configuração e Uso

1. Configuração dos Serviços (Program.cs):

var builder = WebApplication.CreateBuilder(args);
// Adiciona os serviços de Identity e autenticação via Bearer Token
builder.Services.AddAuthentication(IdentityConstants.BearerScheme)
    .AddBearerToken(IdentityConstants.BearerScheme);
builder.Services.AddAuthorization();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddIdentityCore<ApplicationUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddApiEndpoints(); // Habilita a geração dos endpoints de API
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
// Mapeia automaticamente as rotas: /register, /login, /refresh, etc.
app.MapGroup("/identity").MapIdentityApi<ApplicationUser>();
app.Run();  

Quando Utilizar

  • Aplicações SPA ou Mobile Simples: Quando a API serve diretamente uma aplicação Web/Mobile própria e você não precisa que a UI leia o conteúdo do token.

  • Projetos de Foco Rápido (Boilerplate Zero): Cenários onde o foco é entregar autenticação segura com suporte a Refresh Token sem gastar tempo criando serviços de criptografia.

  • Microserviços Internos Confiáveis: Onde o servidor que emite e o servidor que valida compartilham a mesma infraestrutura e chave de proteção de dados.

Conclusão: Escolhendo a Estratégia Ideal

A evolução da autenticação no ASP.NET Core traz duas abordagens robustas, cada uma direcionada a cenários de arquitetura distintos:

Escolha o JWT Bearer "Manual" se você está desenvolvendo APIs públicas, microsserviços desacoplados ou cenários onde o cliente (Frontend SPA, App Mobile ou integrações de terceiros) precisa inspecionar o conteúdo do token para tomadas de decisão na UI. É a melhor opção quando há necessidade de padronização interoperável (IETF RFC 7519) ou arquiteturas distribuídas complexas.

Escolha o Bearer Token Nativo (.NET 8+) se o objetivo for produtividade, baixa manutenção e foco na entrega rápida de APIs com suporte nativo a Refresh Tokens. É a solução ideal para ecossistemas fechados, onde a própria API consome seus dados e o cliente não precisa ler as claims diretamente, garantindo segurança contra inspeção local e eliminando o código boilerplate de gestão de identidade.

A decisão final deve priorizar a complexidade da arquitetura em relação à necessidade de desacoplamento: simplicidade com convenção nativa do framework versus flexibilidade e interoperabilidade total com o padrão JWT.

E estamos conversados..

"Não estejais inquietos por coisa alguma; antes as vossas petições sejam em tudo conhecidas diante de Deus pela oração e súplica, com ação de graças."
Filipenses 4:6

Referências:


José Carlos Macoratti