Hantera JSON-webbtoken under utveckling med dotnet user-jwts

Av Rick Anderson

Kommandoradsverktyget dotnet user-jwts kan skapa och hantera appspecifika lokala JSON-webbtoken (JWT).

Sammanfattning

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

Description

Skapar och hanterar projektspecifika lokala JSON-webbtoken.

Arguments

PROJECT | SOLUTION

MSBuild-projektet som du vill använda ett kommando på. Om ett projekt inte har angetts söker MSBuild i den aktuella arbetskatalogen efter en fil som har ett filnamnstillägg som slutar i proj och använder den filen.

Commands

Befallning Description
klar Ta bort alla utfärdade JWT:er för ett projekt.
create Utfärda en ny JSON-webbtoken.
remove Ta bort en viss JWT.
key Visa eller återställ signeringsnyckeln som används för att utfärda JWTs.
list Visar en lista över JWT:er som utfärdats för projektet.
print Visa information om en viss JWT.

Create

Användning: dotnet user-jwts create [options]

Option Description
-p | --projekt Sökvägen till projektet som ska köras. Standardvärdet för projektet är i den aktuella katalogen.
--schema Det schemanamn som ska användas för den genererade token. Standardvärdet är "Bearer".
-n | --Namn Namnet på den användare som JWT ska skapas för. Standardvärdet är användaren i den aktuella miljön.
--målgrupp Målgrupperna för att skapa JWT. Standardvärden är de URL:er som konfigurerats i projektets launchSettings.json.
--utfärdare Utfärdaren av JWT. Standardvärdet är "dotnet-user-jwts".
--omfattning Ett omfångsanspråk som ska läggas till i JWT. Ange en gång för varje omfång.
--role Ett rollanspråk som ska läggas till i JWT. Ange en gång per roll.
--anspråk Anspråk att lägga till i JWT. Ange en gång för varje krav i formatet "name=value".
--not-before UTC-datum och tid som JWT inte ska vara giltig före i formatet "åååå-MM-dd [[HH:mm[[:ss]]]]". Standardsätts till det datum och den tidpunkt då JWT skapas.
--expires-on UTC-datum och tid då JWT ska upphöra att gälla i formatet "åååå-MM-dd [[[ [HH:mm]]:ss]]". Standardvärdet är 6 månader efter --not-before-datumet. Använd inte det här alternativet tillsammans med alternativet --valid-for.
--valid-for Den period som JWT ska upphöra att gälla efter. Ange med hjälp av ett tal följt av varaktighetstyp som "d" för dagar, "h" för timmar, "m" för minuter och "s" för sekunder, till exempel 365d. Använd inte det här alternativet tillsammans med alternativet --expires-on.
-o | --utdata Det format som ska användas för att visa utdata från kommandot. Kan vara en av "standard", "token" eller "json".
-h | --Hjälp Visa hjälpinformation

Examples

Kör följande kommandon för att skapa ett tomt webbprojekt och lägg till NuGet-paketet Microsoft.AspNetCore.Authentication.JwtBearer :

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

Ersätt innehållet i Program.cs med följande kod:

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

I föregående kod gör en GET-begäran till /secret och returnerar ett 401 Unauthorized-fel. En produktionsapp kan hämta JWT från en säkerhetstokentjänst (STS), kanske som svar på inloggning via en uppsättning autentiseringsuppgifter. I syfte att arbeta med API:et under lokal utveckling dotnet user-jwts kan kommandoradsverktyget användas för att skapa och hantera appspecifika lokala JWT:er.

Verktyget user-jwts liknar verktyget användarhemligheter och kan användas för att hantera värden för appen som endast är giltiga för utvecklaren på den lokala datorn. I själva verket använder user-secrets verktyget user-jwts infrastrukturen för att hantera nyckeln som JWT:erna är signerade med, vilket säkerställer att den lagras säkert i användarprofilen.

Verktyget user-jwts döljer implementeringsinformation, till exempel var och hur värdena lagras. Verktyget kan användas utan att känna till implementeringsinformationen. Värdena lagras i en JSON-fil i den lokala datorns användarprofilmapp:

Filsystemets sökväg

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

Skapa en JWT

Följande kommando skapar en lokal JWT:

dotnet user-jwts create

Föregående kommando skapar en JWT och uppdaterar projektets appsettings.Development.json fil med JSON som liknar följande:

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

Kopiera JWT och ID som skapades i föregående kommando. Använd ett verktyg som Curl för att testa /secret:

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

Var {token} är den tidigare genererade JWT:en.

Visa JWT-säkerhetsinformation

Följande kommando visar JWT-säkerhetsinformationen, inklusive förfallodatum, omfång, roller, tokenhuvud och nyttolast samt den kompakta token:

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

Skapa en token för en specifik användare och omfång

Mer information om alternativ för att skapa finns i Skapa i det här avsnittet.

Följande kommando skapar en JWT för en användare med namnet MyTestUser:

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

Föregående kommando har utdata som liknar följande:

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

Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{Remaining token deleted}

Föregående token kan användas för att testa /secret2 slutpunkten i följande kod:

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