Gerenciar JSON Web Tokens no desenvolvimento com dotnet user-jwts

Por Rick Anderson

A ferramenta de linha de comando dotnet user-jwts pode criar e gerenciar JWTs (Tokens Web JSON) locais específicos do aplicativo.

Este artigo fornece detalhes de sintaxe para o comando e os exemplos.

Sinopse

dotnet user-jwts [<PROJECT>] [command]
dotnet user-jwts [command] -h|--help

Descrição

Cria e gerencia Tokens Web JSON locais específicos do projeto.

Argumentos

PROJECT | SOLUTION

O projeto do MSBuild ao qual aplicar um comando. Se um projeto não for especificado, o MSBuild pesquisará no diretório de trabalho atual um arquivo que tenha uma extensão de arquivo que termine no proj. Em seguida, ele usa esse arquivo para obter as informações do projeto para o comando.

Comandos

Comando Descrição
clear Excluir todos os JWTs emitidos para um projeto.
create Emitir um novo JSON Web Token.
remove Excluir um JWT específico.
key Exibir ou redefinir a chave de assinatura usada para emitir JWTs.
list Liste os JWTs emitidos para o projeto.
print Exibir os detalhes de um JWT específico.

Opções para o comando create

Uso: dotnet user-jwts create [options]

Opção Descrição
-p \| --project O caminho do projeto no qual operar. Usa por padrão o projeto no diretório atual.
--scheme O nome do esquema a ser usado para o token gerado. Usa Bearer como padrão.
-n \| --name O nome do usuário para o qual será criado o JWT. O padrão é o usuário atual do ambiente.
--audience O público-alvo para o qual será criado o JWT. Usa por padrão as URLs configuradas no arquivo launchSettings.json do projeto.
--issuer O emissor do JWT. Usa dotnet-user-jwts como padrão.
--scope Uma declaração de escopo para adicionar ao JWT. Especifique uma vez para cada escopo.
--role Uma declaração de função para adicionar ao JWT. Especifique uma vez para cada função.
--claim Declarações para adicionar ao JWT. Especifique uma vez para cada reivindicação no formato name=value.
--not-before A data e a hora UTC em que o JWT se torna válido, no formato yyyy-MM-dd [[HH:mm[[:ss]]]]. O valor padrão é a data e a hora em que o JWT é criado.
--expires-on A data e a hora UTC em que o JWT expira, no formato yyyy-MM-dd [[[ [HH:mm]]:ss]]. É definido por padrão como seis meses após a data --not-before. Não use esta opção com a opção --valid-for.
--valid-for O tempo durante o qual o JWT permanece válido. Quando esse momento é atingido, o JWT expira. Especifique um número seguido pelo tipo de duração (d dias, h horas, m minutos, s segundos), como 365d. Não use esta opção com a opção --expires-on.
-o \| --output O formato a ser usado para exibir a saída do comando: default, tokenou json.
-h \| --help Mostrar informações de ajuda para o comando.

Exemplos

Execute os seguintes comandos para criar um projeto Web vazio e adicionar o pacote NuGet Microsoft.AspNetCore.Authentication.JwtBearer:

dotnet new web -o MyJWT
cd MyJWT
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

Substitua o conteúdo do arquivo Program.cs pelo seguinte código:

using System.Security.Claims;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization();
builder.Services.AddAuthentication("Bearer").AddJwtBearer();

var app = builder.Build();

app.UseAuthorization();

app.MapGet("/", () => "Hello, World!");
app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret")
    .RequireAuthorization();

app.Run();

No código anterior, uma solicitação GET para o /secret ponto de extremidade retorna um 401 Unauthorized erro. Um aplicativo de produção pode obter o JWT de um serviço de token de segurança, talvez em resposta à entrada com credenciais. Quando você usa a API durante o desenvolvimento local, a dotnet user-jwts ferramenta de linha de comando pode ser usada para criar e gerenciar JWTs locais específicos do aplicativo.

A ferramenta user-jwts é semelhante, em conceito, à ferramenta user-secrets. Ele pode ser usado para gerenciar valores para o aplicativo válidos apenas para o desenvolvedor no computador local. Na verdade, a user-jwts ferramenta utiliza a user-secrets infraestrutura para gerenciar a chave com a qual os JWTs estão assinados. Essa abordagem garante que a chave seja armazenada com segurança no perfil do usuário.

A ferramenta user-jwts oculta detalhes de implementação, como onde e como os valores são armazenados. A ferramenta pode ser usada sem conhecer os detalhes da implementação.

Os valores são armazenados em um arquivo JSON na pasta de perfil de usuário do computador local:

  • Windows: %APPDATA%\Microsoft\UserSecrets<secrets_GUID>\user-jwts.json

  • Linux/macOS: ~/.microsoft/usersecrets/<secrets_GUID>/user-jwts.json

Criação de um JWT

O seguinte comando cria um JWT local:

dotnet user-jwts create

O comando anterior cria um JWT e atualiza o arquivo de projeto appsettings.Development.json com JSON semelhante ao seguinte exemplo:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Authentication": {
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "http://localhost:8401",
          "https://localhost:44308",
          "http://localhost:5182",
          "https://localhost:7076"
        ],
        "ValidIssuer": "dotnet-user-jwts"
      }
    }
  }
}

Copie o JWT e o ID criado no comando anterior. Use uma ferramenta como Curl para testar o endpoint /secret, em que {token} é o JWT gerado anteriormente:

curl -i -H "Authorization: Bearer {token}" https://localhost:{port}/secret

Exibição de informações de segurança do JWT

O seguinte comando exibe as informações de segurança do JWT, incluindo expiração, escopos, funções, cabeçalho e conteúdo do token e o token compacto:

dotnet user-jwts print {ID} --show-all

Criação de um token para um usuário e escopo específicos

O comando a seguir cria um JWT para um usuário chamado MyTestUser. Para ver as opções create compatíveis, consulte a seção Opções para o comando create.

dotnet user-jwts create --name MyTestUser --scope "myapi:secrets"

O comando anterior tem uma saída semelhante ao seguinte exemplo:

New JWT saved with ID '43e0b748'.
Name: MyTestUser
Scopes: myapi:secrets

Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{Remaining token deleted}

O token anterior pode ser usado para testar o ponto de extremidade /secret2 no seguinte código:

using System.Security.Claims;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization();
builder.Services.AddAuthentication("Bearer").AddJwtBearer();

var app = builder.Build();

app.MapGet("/", () => "Hello, World!");
app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret")
    .RequireAuthorization();
app.MapGet("/secret2", () => "This is a different secret!")
    .RequireAuthorization(p => p.RequireClaim("scope", "myapi:secrets"));

app.Run();