Управление веб-токенами JSON в разработке с помощью dotnet user-jwts

Автор: Рик Андерсон (Rick Anderson)

Инструмент командной строки dotnet user-jwts может создавать локальные JSON Web Tokens (JWT), специфичные для приложения, и управлять ими.

В этой статье приведены сведения о синтаксисе команды и примеров.

Краткие сведения

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

Описание

Создает и управляет определенными локальными веб-токенами JSON для проекта.

Аргументы

PROJECT | SOLUTION

Проект MSBuild, к которому применяется команда. Если проект не указан, MSBuild выполняет поиск текущего рабочего каталога для файла с расширением файла, заканчивающегося proj. Затем он использует этот файл для получения сведений о проекте для команды.

Команды

Команда Описание
clear Удалите все выпущенные токены JWT для проекта.
create Выдача нового веб-токена JSON.
remove Удалите указанный JWT.
key Отобразить или сбросить ключ подписи, используемый для выпуска JWT.
list Список JWTs, выданных для проекта.
print Отображение сведений о заданном JWT.

Параметры команды создания

Использование: dotnet user-jwts create [options]

Вариант Описание
-p \| --project Путь к проекту, с которым будет выполняться операция. По умолчанию используется проект в текущем каталоге.
--scheme Имя схемы, используемое для создаваемого токена. По умолчанию — Bearer.
-n \| --name Имя пользователя для создания JWT. По умолчанию используется текущий пользователь среды.
--audience Аудитории, для которых создаётся JWT. По умолчанию используются URL-адреса, настроенные в файле проекта launchSettings.json.
--issuer Эмитент JWT. По умолчанию — dotnet-user-jwts.
--scope Утверждение о правах доступа, добавляемое в JWT. Укажите один раз для каждой области действия.
--role Утверждение о роли, добавляемое в JWT. Укажите один раз для каждой роли.
--claim Утверждения, добавляемые в JWT. Укажите по одному разу для каждого утверждения в формате name=value.
--not-before Дата и время в формате UTC, в которое JWT вступает в силу, в формате yyyy-MM-dd [[HH:mm[[:ss]]]]. По умолчанию используется дата и время создания JWT.
--expires-on Дата и время в формате yyyy-MM-dd [[[ [HH:mm]]:ss]]UTC, в течение которого истекает срок действия JWT. Значение по умолчанию — шесть месяцев после --not-before даты. Не используйте этот параметр с параметром --valid-for .
--valid-for Время, в течение которого JWT остается действительным. Когда наступает это время, срок действия JWT истекает. Укажите число, за которым следует тип длительности (d дни, часы, hm минуты, s секунды), например 365d. Не используйте этот параметр с параметром --expires-on .
-o \| --output Формат, используемый для отображения выходных данных из команды: default, tokenили json.
-h \| --help Показать справку по команде.

Примеры

Выполните следующие команды, чтобы создать пустой веб-проект и добавить пакет NuGet Microsoft.AspNetCore.Authentication.JwtBearer :

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

Замените содержимое файла Program.cs следующим кодом:

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();

В приведенном выше коде запрос GET к /secret конечной точке возвращает ошибку 401 Unauthorized . Производственное приложение может получить JWT из службы маркеров безопасности, возможно, в ответ на вход с помощью учетных данных. При локальной разработке с использованием API средство командной строки dotnet user-jwts можно использовать для создания локальных JWT для отдельных приложений и управления ими.

Средство user-jwts аналогично по своей концепции средству user-secrets. Его можно использовать для управления значениями приложения, которые действительны только для разработчика на локальном компьютере. На самом деле средство user-jwts использует инфраструктуру user-secrets для управления ключом, которым подписываются JWT. Этот подход гарантирует безопасное хранение ключа в профиле пользователя.

Средство user-jwts скрывает сведения о реализации, например, где и как хранятся значения. Средство можно использовать без знания сведений о реализации.

Значения хранятся в JSON-файле в папке профиля пользователя локального компьютера:

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

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

Создание JWT

Следующая команда создает локальный JWT:

dotnet user-jwts create

Предыдущая команда создает JWT и обновляет файл проекта appsettings.Development.json с помощью JSON, как показано в следующем примере:

{
  "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"
      }
    }
  }
}

Скопируйте JWT и объект ID, созданный в предыдущей команде. Используйте такой инструмент, как Curl, чтобы протестировать конечную точку /secret, где {token} — это ранее созданный JWT:

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

Отображение сведений о безопасности JWT

Следующая команда отображает информацию о безопасности JWT, включая срок действия, области действия, роли, заголовок и полезную нагрузку токена, а также компактное представление токена:

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

Создать токен для конкретного пользователя и области действия

Следующая команда создает JWT для пользователя с именем MyTestUser. Поддерживаемые create параметры см. в разделе "Параметры для создания команды ".

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

Предыдущая команда имеет выходные данные, аналогичные следующему примеру:

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

Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{Remaining token deleted}

Предыдущий маркер можно использовать для тестирования конечной /secret2 точки в следующем коде:

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();