Gérer les jetons web JSON dans le développement avec dotnet user-jwts

Par Rick Anderson

L’outil en ligne de commande dotnet user-jwts peut créer et gérer des jetons web JSON (JWT) locaux spécifiques à l’application.

Synopsis

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

Description

Crée et gère des jetons web JSON locaux spécifiques au projet.

Arguments

PROJECT | SOLUTION

Projet MSBuild sur lequel appliquer une commande. Si vous ne spécifiez pas de projet, MSBuild recherche dans le répertoire de travail actuel un fichier avec une extension se terminant par proj et l’utilise.

Commandes

Command Description
clear Supprimez tous les JWT émis pour un projet.
create Émettre un nouveau jeton JSON Web.
suppression Supprimez un JWT donné.
key Affichez ou réinitialisez la clé de signature utilisée pour émettre des JWT.
list Répertorie les JWT émis pour le projet.
print Affichez les détails d’un JWT donné.

Créer

Utilisation : dotnet user-jwts create [options]

Option Description
-p | --project Chemin d’accès du projet sur lequel opérer. Par défaut, le projet est dans le répertoire actif.
--scheme Nom du schéma à utiliser pour le jeton généré. La valeur par défaut est « Porteur ».
-n | --nom Nom de l’utilisateur pour lequel créer le JWT. Par défaut, l’utilisateur d’environnement actuel.
--audience Audiences pour laquelle créer le JWT. Par défaut, les URL configurées dans le fichier launchSettings.json du projet.
--émetteur Émetteur du JWT. La valeur par défaut est « dotnet-user-jwts ».
--scope Revendication d’étendue à ajouter au JWT. Spécifiez une fois pour chaque étendue.
--role Revendication de rôle à ajouter au JWT. Spécifiez une fois pour chaque rôle.
--revendication Revendications à ajouter au JWT. Spécifiez une fois pour chaque revendication au format « name=value ».
--not-before La date et l’heure UTC avant lesquelles le JWT ne doit pas être valide au format « aaaa-MM-jj [[HH:mm[[:ss]]]] ». La valeur par défaut est la date et l’heure de création du JWT.
--expires-on La date et l’heure UTC auxquelles le JWT doit expirer au format « aaaa-MM-jj [[[ [HH:mm]]:ss]] ». Par défaut, 6 mois après la date --not-before. N'utilisez pas cette option conjointement avec l'option --valid.
--valid-for Période après laquelle JWT doit expirer. Spécifiez un nombre suivi d’un type de durée comme « j » pour les jours, « h » pour les heures, « m » pour les minutes et « s » pour les secondes, par exemple 365j ». N'utilisez pas cette option conjointement avec l'option --expires-on
-o | --Sortie Format à utiliser pour afficher la sortie de la commande. Il peut s’agir de « default », « token » ou « json ».
-h | --help Afficher les informations d’aide

Exemples

Exécutez les commandes suivantes pour créer un projet web vide et ajouter le package NuGet Microsoft.AspNetCore.Authentication.JwtBearer :

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

Remplacez le contenu de Program.cs par le code suivant :

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

Dans le code précédent, une demande GET à /secret renvoie une erreur 401 Unauthorized. Une application de production peut obtenir le JWT à partir d’un service de jeton de sécurité (STS), peut-être en réponse à la connexion via un ensemble d’informations d’identification. Dans le but d’utiliser l’API pendant le développement local, l’outil dotnet user-jwts en ligne de commande peut être utilisé pour créer et gérer des JWTs locaux spécifiques à l’application.

L’outil user-jwts est similaire dans son concept à l’outil de secrets utilisateur. Il peut être utilisé pour gérer les valeurs de l’application qui ne sont valides que pour le développeur sur l’ordinateur local. En fait, l’outil user-jwts utilise l’infrastructure user-secrets pour gérer la clé avec laquelle les JWT sont signés, en veillant à ce qu’elle soit stockée en toute sécurité dans le profil utilisateur.

L’outil user-jwts masque les détails de l’implémentation, tels que l’emplacement et la façon dont les valeurs sont stockées. L’outil peut être utilisé sans connaître les détails de l’implémentation. Les valeurs sont stockées dans un fichier JSON dans le dossier de profil utilisateur de la machine locale :

Chemin du système de fichiers :

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

Créer un JWT

La commande suivante crée un JWT local :

dotnet user-jwts create

La commande précédente crée un JWT et met à jour le fichier du appsettings.Development.json projet avec JSON comme suit :

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

Copiez le JWT et le ID créé dans la commande précédente. Utilisez un outil comme Curl pour tester /secret :

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

{token} est le JWT généré précédemment.

Afficher les informations de sécurité JWT

La commande suivante affiche les informations de sécurité JWT, notamment l’expiration, les étendues, les rôles, l’en-tête et la charge utile du jeton, ainsi que le jeton compact :

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

Créer un jeton pour un utilisateur et une étendue spécifiques

Consultez Créer dans cette rubrique pour connaître les options de création prises en charge.

La commande suivante crée un JWT pour un utilisateur nommé MyTestUser :

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

La commande précédente affiche une sortie similaire à ce qui suit :

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

Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{Remaining token deleted}

Le jeton précédent peut être utilisé pour tester le point de terminaison /secret2 dans le code suivant :

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