Pour configurer le code de votre API web protégée, vous devez comprendre ce qui suit :
Ce qui définit les API comme étant protégées.
Comment configurer un jeton du porteur.
Comment valider le jeton.
Qu’est-ce qui définit les API ASP.NET et ASP.NET Core comme étant protégées ?
Comme les applications web, les API web ASP.NET et ASP.NET Core sont protégées parce que leurs actions de contrôleur sont préfixées par l’attribut [Authorize]. Les actions de contrôleur peuvent être appelées uniquement si l’API est appelée avec une identité autorisée.
Considérez les questions suivantes :
Seule une application peut appeler une API web. Comment l’API connaît-elle l’identité de l’application qui l’appelle ?
Si l’application appelle l’API au nom d’un utilisateur, quelle est l’identité de celui-ci ?
Jeton du porteur
Le jeton du porteur qui est défini dans l’en-tête lorsque l’application est appelée contient des informations sur l’identité de l’application. Il contient également des informations sur l’utilisateur, sauf si l’application web accepte les appels de service à service à partir d’une application démon.
Voici un exemple de code C# qui présente un client appelant l’API après avoir acquis un jeton de la bibliothèque d’authentification Microsoft pour .NET (MSAL.NET) :
var scopes = new[] {$"api://.../access_as_user"};
var result = await app.AcquireToken(scopes)
.ExecuteAsync();
httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
Important
Une application cliente demande le jeton du porteur à la plateforme d’identités Microsoft pour l’API web. L’API est la seule application qui doive vérifier le jeton et afficher les revendications qu’il contient. Les applications clientes ne doivent jamais tenter d’inspecter les revendications contenues dans les jetons
À l’avenir, l’API web pourrait exiger que le jeton soit chiffré. Cette exigence empêcherait l’accès des applications clientes capables d’afficher les jetons d’accès.
Configuration de JwtBearer
Cette section décrit comment configurer un jeton du porteur.
Fichier de configuration
Vous devez spécifier le TenantId seulement si vous souhaitez accepter des jetons d’accès à partir d’un locataire unique (application métier). Sinon, vous pouvez laisser la valeur common. Les différentes valeurs peuvent être :
Un GUID (ID de locataire = ID d’annuaire)
common peut être n’importe quelle organisation ou tout compte personnel
organizations peut être n’importe quelle organisation
Les consumers sont des comptes personnels Microsoft
Utilisation d’un URI d’ID d’application personnalisé pour une API web
Si vous avez accepté l’URI ID d’application par défaut proposé par le portail Azure, vous n’avez pas besoin de spécifier le public (consultez URI et étendues de l’ID d’application). Dans le cas contraire, ajoutez une propriété Audience dont la valeur est l’URI ID d’application de votre API web. Il commence généralement par api://.
Quand une application est appelée sur une action de contrôleur qui contient un attribut [Authorize], ASP.NET et ASP.NET Core extraient le jeton d’accès à partir du jeton du porteur dans l’en-tête d’autorisation. Le jeton d’accès est ensuite transmis à l’intergiciel JwtBearer qui appelle Microsoft IdentityModel Extensions pour .NET.
Microsoft vous recommande d’utiliser le package NuGet Microsoft.Identity.Web lors du développement d’une API web avec ASP.NET Core.
Microsoft.Identity.Web fournit le ciment entre ASP.NET Core, l’intergiciel d’authentification et la bibliothèque d’authentification Microsoft (MSAL) pour .NET. Il favorise une expérience développeur plus claire et plus robuste, et tire parti de la puissance de la plateforme d’identités Microsoft et d’Azure AD B2C.
ASP.NET pour .NET 6.0
Pour créer un projet d’API web qui utilise Microsoft.Identity.Web, utilisez un modèle de projet dans l’interface CLI .NET 6.0 ou Visual Studio.
CLI Dotnet core
# Create new web API that uses Microsoft.Identity.Web
dotnet new webapi --auth SingleOrg
Visual Studio - Pour créer un projet d’API web dans Visual Studio, sélectionnez Fichier>Nouveau>Projet>API web ASP.NET Core.
Les modèles de projet .NET CLI et Visual Studio créent un fichier Program.cs, qui ressemble à cet extrait de code. Notez la directive using Microsoft.Identity.Web ainsi que les lignes contenant l’authentification et l’autorisation.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Microsoft vous recommande d’utiliser le package NuGet Microsoft.Identity.Web.OWIN lors du développement d’une API web avec ASP.NET.
Microsoft.Identity.Web.OWIN fournit le ciment entre ASP.NET, l’intergiciel d’authentification ASP.NET et la bibliothèque d’authentification Microsoft (MSAL) pour .NET. Il favorise une expérience développeur plus claire et plus robuste, et tire parti de la puissance de la plateforme d’identités Microsoft et d’Azure AD B2C.
Il utilise le même fichier de configuration que ASP.NET Core (appsettings.json) et vous devez vous assurer que ce fichier est copié avec la sortie de votre projet (copie de propriété toujours dans les propriétés du fichier dans Visual Studio ou dans .csproj)
Microsoft.Identity.Web.OWIN ajoute une méthode d’extension à IAppBuilder nommée AddMicrosoftIdentityWebApi. Cette méthode prend comme paramètre un instance de OwinTokenAcquirerFactory que vous obtenez l’appel OwinTokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>() et qui fait apparaître un instance auquel vous pouvez ajouter de IServiceCollection nombreux services pour appeler des API en aval ou configurer le cache de jetons.
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Owin;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web.OWIN;
using System.Web.Services.Description;
namespace OwinWebApp
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
OwinTokenAcquirerFactory factory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
app.AddMicrosoftIdentityWebApp(factory);
factory.Services
.Configure<ConfidentialClientApplicationOptions>(options => { options.RedirectUri = "https://localhost:44386/"; })
.AddMicrosoftGraph()
.AddDownstreamApi("DownstreamAPI1", factory.Configuration.GetSection("DownstreamAPI"))
.AddInMemoryTokenCaches();
factory.Build();
}
}
}
--
Validation du jeton
Dans l’extrait de code précédent, l’intergiciel JwtBearer, tout comme le middleware OpenID Connect dans des applications web, valide le jeton en fonction de la valeur de TokenValidationParameters. Le jeton est déchiffré si nécessaire, les revendications extraites et la signature vérifiée. L’intergiciel valide ensuite le jeton en vérifiant les points suivants :
Audience: Le jeton est destiné à l’API web.
Sub : Il a été émis pour une application autorisée à appeler l’API web.
Émetteur : Il a été émis par un service d’émission de jeton de sécurité (STS) approuvé.
Expiration : Sa durée de vie s’inscrit dans la plage valide.
Signature : Il n’a pas été falsifié.
Il peut également y avoir des validations spéciales. Par exemple, il est possible de valider le fait que les clés de signature, quand elles sont incorporées dans un jeton, sont approuvées et que le jeton n’est pas en cours de réexécution. Enfin, certains protocoles nécessitent des validations spécifiques.
S’assure que le jeton est destiné à l’application qui le valide pour vous.
ValidateIssuer
S’assure que le jeton a été émis par un STS approuvé, ce qui signifie qu’il s’agit d’une personne à qui vous faites confiance.
ValidateIssuerSigningKey
S’assure que l’application qui valide le jeton approuve la clé utilisée pour signer le jeton Il existe un cas particulier où la clé est incorporée dans le jeton. Cependant, ce cas ne se produit généralement pas.
ValidateLifetime
S’assure que le jeton est encore ou déjà valide. Le validateur vérifie si la durée de vie du jeton est comprise dans la plage spécifiée par les revendications notbefore et expires.
ValidateSignature
S’assure que le jeton n’a pas été falsifié.
ValidateTokenReplay
S’assure que le jeton n’est pas en cours de réexécution Il existe un cas particulier pour certains protocoles d’utilisation unique.
Personnalisation de la validation des jetons
Les validateurs sont associés aux propriétés de la classe TokenValidationParameters. Les propriétés sont initialisées à partir de la configuration ASP.NET et ASP.NET Core.
Dans la plupart des cas, vous n’avez pas besoin de modifier les paramètres. Les applications qui ne sont pas à locataire unique sont des exceptions. Ces applications web acceptent des utilisateurs de toute organisation ou de comptes Microsoft personnels. Dans ce cas, les émetteurs doivent être validés. Microsoft.Identity.Web s’occupe également de la validation de l’émetteur.
Dans ASP.NET Core, si vous souhaitez personnaliser les paramètres de validation du jeton, utilisez l’extrait de code suivant dans votre Startup.cs :
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration);
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.ValidAudiences = new[] { /* list of valid audiences */};
});
Pour le MVC d’ASP.NET, l’exemple de code suivant montre comment effectuer une validation de jeton personnalisée :
Vous pouvez également valider les jetons d’accès entrants dans Azure Functions. Vous trouverez des exemples de cette validation dans les exemples de code suivants sur GitHub :