Authentification et autorisation dans les API minimales

Les API minimales prennent en charge toutes les options d’authentification et d’autorisation disponibles dans ASP.NET Core et fournissent des fonctionnalités supplémentaires pour améliorer l’expérience d’utilisation de l’authentification.

Concepts clés de l’authentification et de l’autorisation

L’authentification est le processus de détermination de l’identité d’un utilisateur. L’autorisation est le processus consistant à déterminer si un utilisateur a accès à une ressource. Les scénarios d’authentification et d’autorisation partagent une sémantique d’implémentation similaire dans ASP.NET Core. L’authentification est gérée par le service d’authentification, IAuthenticationService, qui est utilisé par l’intergiciel d’authentification. L’autorisation est gérée par le service d’autorisation , IAuthorizationService, qui est utilisé par l’intergiciel d’autorisation.

Le service d’authentification utilise des gestionnaires d’authentification inscrits pour effectuer des actions liées à l’authentification. Par exemple, une action liée à l’authentification est l’authentification d’un utilisateur ou la déconnexion d’un utilisateur. Les schémas d’authentification sont des noms utilisés pour identifier de manière unique un gestionnaire d’authentification et ses options de configuration. Les gestionnaires d’authentification sont responsables de l’implémentation des stratégies d’authentification et de la génération des revendications d’un utilisateur en fonction d’une stratégie d’authentification particulière, telle qu’OAuth ou OIDC. Les options de configuration sont également propres à la stratégie et fournissent au gestionnaire une configuration qui affecte le comportement d’authentification, comme les URI de redirection.

Il existe deux stratégies pour déterminer l’accès utilisateur aux ressources dans la couche d’autorisation :

Dans ASP.NET Core, les deux stratégies sont capturées dans une exigence d’autorisation. Le service d’autorisation tire profit des gestionnaires d’autorisation pour déterminer si un utilisateur particulier répond ou non aux exigences d’autorisation appliquées à une ressource.

Activation de l’authentification dans les applications minimales

Pour activer l’authentification, appelez AddAuthentication pour inscrire les services d’authentification requis sur le fournisseur de services de l’application.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication();
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

En règle générale, une stratégie d’authentification spécifique est utilisée. Dans l’exemple suivant, l’application est configurée avec prise en charge de l’authentification basée sur le porteur JWT. Cet exemple montre comment utiliser les API disponibles dans le package NuGet Microsoft.AspNetCore.Authentication.JwtBearer.

var builder = WebApplication.CreateBuilder(args);
// Requires Microsoft.AspNetCore.Authentication.JwtBearer
builder.Services.AddAuthentication().AddJwtBearer();
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

Par défaut, le WebApplication enregistre automatiquement les intergiciels d’authentification et d’autorisation si certains services d’authentification et d’autorisation sont activés. Dans l’exemple suivant, il n’est pas nécessaire d’appeler UseAuthentication ou UseAuthorization pour enregistrer les intergiciels, car WebApplication le fait automatiquement après que AddAuthentication ou AddAuthorization sont appelés.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

Dans certains cas, comme le contrôle de l’ordre des intergiciels, il est nécessaire d’enregistrer explicitement l’authentification et l’autorisation. Dans l’exemple suivant, l’intergiciel d’authentification s’exécute après l’exécution de l’intergiciel CORS. Pour plus d’informations sur les intergiciels et ce comportement automatique, consultez Intergiciels dans les applications d’API minimales.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors();
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();

var app = builder.Build();

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/", () => "Hello World!");
app.Run();

Configuration de la stratégie d’authentification

Les stratégies d’authentification prennent généralement en charge diverses configurations qui sont chargées via des options. Les applications minimales prennent en charge des options de chargement à partir de la configuration pour les stratégies d’authentification suivantes :

L’infrastructure ASP.NET Core s’attend à trouver ces options dans la section Authentication:Schemes:{SchemeName} de configuration. Dans l’exemple suivant, deux schémas différents, Bearer et LocalAuthIssuer, sont définis avec leurs options respectives. L’option Authentication:DefaultScheme peut être utilisée pour configurer la stratégie d’authentification par défaut utilisée.

{
  "Authentication": {
    "DefaultScheme":  "LocalAuthIssuer",
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "https://localhost:7259",
          "http://localhost:5259"
        ],
        "ValidIssuer": "dotnet-user-jwts"
      },
      "LocalAuthIssuer": {
        "ValidAudiences": [
          "https://localhost:7259",
          "http://localhost:5259"
        ],
        "ValidIssuer": "local-auth"
      }
    }
  }
}

Dans Program.cs, deux stratégies d’authentification basées sur le porteur JWT sont inscrites, avec le :

  • nom de schéma « Bearer ».
  • nom de schéma « LocalAuthIssuer ».

« Bearer » est le schéma par défaut typique dans les applications avec support activées basées sur le porteur JWT, mais le schéma par défaut peut être remplacé en définissant la propriété DefaultScheme comme dans l’exemple précédent.

Le nom du schéma est utilisé pour identifier de manière unique une stratégie d’authentification et est utilisé comme clé de recherche lors de la résolution des options d’authentification à partir de config, comme illustré dans l’exemple suivant :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication()
  .AddJwtBearer()
  .AddJwtBearer("LocalAuthIssuer");
  
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

Configuration de stratégies d’autorisation dans des applications minimales

L’authentification est utilisée pour identifier et valider l’identité des utilisateurs par rapport à une API. L’autorisation est utilisée pour valider et vérifier l’accès aux ressources dans une API et est facilitée par le IAuthorizationService enregistré par la méthode d’extension AddAuthorization. Dans le scénario suivant, une ressource /hello qui nécessite qu’un utilisateur présente une revendication de rôle admin, avec une revendication d’étendue greetings_api, est ajoutée.

La configuration des exigences d’autorisation sur une ressource est un processus en deux étapes qui nécessite :

  1. La configuration globale des exigences d’autorisation dans une stratégie.
  2. L’application de stratégies individuelles aux ressources.

Dans le code suivant, AddAuthorizationBuilder est appelé et :

  • Ajoute des services liés à l’autorisation au conteneur DI.
  • Retourne un AuthorizationBuilder qui peut être utilisé pour inscrire directement des stratégies d’authentification.

Le code crée une nouvelle stratégie d’autorisation, nommée admin_greetings, qui encapsule deux exigences d’autorisation :

  • Une exigence basée sur les rôles via RequireRole pour les utilisateurs disposant d’un rôle admin.
  • Une exigence, basée sur les revendications par RequireClaim, à laquelle l’utilisateur doit fournir une revendication d’étendue greetings_api.

La stratégie admin_greetings est fournie en tant que stratégie requise pour le point de terminaison /hello.

using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorizationBuilder()
  .AddPolicy("admin_greetings", policy =>
        policy
            .RequireRole("admin")
            .RequireClaim("scope", "greetings_api"));

var app = builder.Build();

app.MapGet("/hello", () => "Hello world!")
  .RequireAuthorization("admin_greetings");

app.Run();

Utiliser dotnet user-jwts pour les tests de développement

Tout au long de cet article, une application configurée avec l’authentification basée sur le porteur JWT est utilisée. L’authentification basée sur le porteur JWT nécessite que les clients présentent un jeton dans l’en-tête de requête pour valider leur identité et leurs revendications. En règle générale, ces jetons sont émis par une autorité centrale, telle qu’un serveur d’identité.

Lors du développement sur l’ordinateur local, l’outil dotnet user-jwts peut être utilisé pour créer des jetons du porteur.

dotnet user-jwts create

Remarque

Lorsqu’il est appelé sur un projet, l’outil ajoute automatiquement les options d’authentification correspondant au jeton généré à appsettings.json.

Les jetons peuvent être configurés avec diverses personnalisations. Par exemple, pour créer un jeton pour le rôle admin et l’étendue greetings_api attendus par la stratégie d’autorisation dans le code précédent :

dotnet user-jwts create --scope "greetings_api" --role "admin"

Le jeton généré peut ensuite être envoyé dans le cadre de l’en-tête dans l’outil de test de votre choix. Par exemple, avec curl :

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

Pour plus d’informations sur l’outil dotnet user-jwts, consultez la documentation complète.