使用 dotnet user-jwts 管理开发中的 JSON Web 令牌

作者:Rick Anderson

dotnet user-jwts 命令行工具可以创建和管理特定于应用的本地 JSON Web 令牌 (JWT)。

摘要

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

说明

创建和管理特定于项目的本地 JSON Web 令牌。

参数

PROJECT | SOLUTION

要对其应用命令的 MSBuild 项目。 如果未指定项目,MSBuild 会在当前工作目录中搜索文件扩展名以 proj 结尾的文件并使用该文件。

命令

命令 说明
clear 删除为项目颁发的所有 JWT。
create 颁发新的 JSON Web 令牌。
remove 删除给定的 JWT。
key 显示或重置用于颁发 JWT 的签名密钥。
list 列出为项目颁发的 JWT。
print 显示给定 JWT 的详细信息。

创建

用法:dotnet user-jwts create [options]

选项 说明
-p | --project 要操作的项目的路径。 默认为当前目录中的项目。
--scheme 要对生成的令牌使用的方案名称。 默认为“持有者”。
-n | --name 要为其创建 JWT 的用户的名称。 默认为当前环境用户。
--audience 要为其创建 JWT 的受众。 默认为在项目的 launchSettings.json 中配置的 URL。
--issuer JWT 的颁发者。 默认为“dotnet-user-jwts”。
--scope 要添加到 JWT 的范围声明。 为每个范围指定一次。
--role 要添加到 JWT 的角色声明。 为每个角色指定一次。
--claim 要添加到 JWT 的声明。 为每个声明指定一次(采用“name=value”格式)。
--not-before JWT 生效的日期和时间 (UTC),采用“yyyy-MM-dd [[HH:mm[[:ss]]]]”格式。 默认为创建 JWT 的日期和时间。
--expires-on JWT 到期的日期和时间 (UTC),采用“yyyy-MM-dd [[[ [HH:mm]]:ss]]”格式。 默认为 --not-before 日期之后的 6 个月。 不要将此选项与 --valid-for 选项一起使用。
--valid-for JWT 的有效期。 使用一个数字进行指定,后跟持续时间类型,例如“d”表示天、“h”表示小时、“m”表示分钟、“s”表示秒,例如 365d。 不要将此选项与 --expires-on 选项一起使用。
-o | --output 用于显示命令输出的格式。 可以是“default”、“token”或“json”之一。
-h | --help 显示帮助信息

示例

运行以下命令来创建一个空的 Web 项目,并添加 Microsoft.AspNetCore.Authentication.JwtBearer NuGet 包:

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

在上述代码中,对 /secret 的 GET 请求会返回 401 Unauthorized 错误。 生产应用可能会从 安全令牌服务 (STS) 获取 JWT,它可能用来响应通过一组凭据进行的登录。 为了在本地开发期间使用 API,可使用 dotnet user-jwts 命令行工具创建和管理特定于应用的本地 JWT。

user-jwts 工具在概念上与 user-secrets 工具类似,可用于管理仅对本地计算机上的开发人员有效的应用值。 事实上,user-jwts 工具利用 user-secrets 基础结构来管理 JWT 签名时使用的密钥,确保该密钥安全地存储在用户配置文件中。

user-jwts 工具会隐藏实现详细信息,例如值的存储位置和存储方法。 可在不知道实现详细信息的情况下使用该工具。 这些值存储在本地计算机的用户配置文件文件夹中的 JSON 文件中:

文件系统路径:

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

创建 JWT

以下命令会创建一个本地 JWT:

dotnet user-jwts create

上述命令会创建一个 JWT 并使用 JSON 更新项目的 appsettings.Development.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

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

其中,{token} 是之前生成的 JWT。

显示 JWT 安全信息

以下命令会显示 JWT 安全信息和紧凑令牌,其中安全信息包括过期时间、范围、角色、令牌标头和有效负载:

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

为特定用户和范围创建令牌

有关支持的创建选项,请参阅本主题中的创建

以下命令会为名为 MyTestUser 的用户创建一个 JWT:

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