S’il s’agit d’applications, ressources ou services nécessitant au préalable une authentification pour l’accès, chaque couche devra implémenter son propre mécanisme d’authentification et de gestion des autorisations. Dans de nombreux cas, en utilisant une seule base de données pour la gestion des utilisateurs et des accès.
Au lieu de dupliquer la logique d’authentification dans chaque application ou service, il est plus judicieux de se tourner vers un service de gestion sécurisée de jetons (STS – Secure Token Service). Ce dernier servira de service d’authentification unique pour l’ensemble de vos ressources.
Concrètement, lorsqu’un utilisateur voudra accéder à partir de son navigateur, par exemple, à l’application Web, cette dernière ne procédera pas directement à l’authentification de celui-ci. L’application Web procédera plutôt à une redirection de ce dernier vers le service de gestion sécurisée de jeton. L’utilisateur s’authentifira auprès du STS et obtiendra un jeton de sécurité. Ensuite, il sera redirigé vers l’application Web à laquelle il voulait accéder initialement. Si à partir de cette application, il accède, par exemple, à une Web API, ce jeton pourra être utilisé pour confirmer son identité et valider ses droits d’accès à cette ressource.
Par ailleurs, via la fédération, il pourra accéder à une autre application Web de l’entreprise sans avoir besoin de s’authentifier à nouveau.
Sur le marché, il existe de nombreuses solutions payantes et open source permettant de mettre en place un STS. L’une des solutions open source les plus célèbres dans l’écosystème .NET est IdentityServer.
C’est quoi IdentityServer
IdentityServer est une solution open source .NET de gestion d’identité et de contrôle d’accès. Il repose sur les protocoles OpenID Connect et OAuth 2.0.
IdentityServer peut être utilisé par les entreprises pour mettre en place une solution pour :
- la protection de leurs ressources,
- l’authentification des utilisateurs via une base de données ou des fournisseurs externes d’identité (Microsoft, Google, Facebook, etc.);
- la gestion des sessions et la fédération (single sign-on);
- la génération des jetons pour les clients;
- la validation des jetons et bien plus.
Pour cette série de billets, nous allons utiliser IdentityServer4. Cette version a été développée en utilisant ASP.NET Core.
1 – Création du projet et configuration de IdentityServer
1-1 Création du projet
Nous allons commencer à partir de zéro en créant une nouvelle application ASP.NET Core qui sera notre IdentityServer. Elle doit être basée sur le modèle « Vide » et n’avoir aucune authentification :
Une fois le nouveau projet créé, vous devez ajouter une référence au package IdentityServer4, en utilisant le gestionnaire de packages NuGet :
Si vous utilisez Visual Studio Code, vous pouvez utiliser la commande :
Code : | Sélectionner tout |
Dotnet add package IdentityServer4
Vous aurez besoin d’enregistrer IdentityServer dans le conteneur d’injection de dépendances de ASP.NET Core et ajouter le middleware de ce dernier dans le pipeline HTTP du Framework.
Pour enregistrer IdentityServer, vous devez éditer le fichier Startup.cs et modifier la méthode ConfiguresServices comme suit :
Code C# : | Sélectionner tout |
1 2 3 4 5 | public void ConfigureServices(IServiceCollection services) { services.AddIdentityServer() .AddDeveloperSigningCredential(); } |
AddIdentityServer est une méthode d’extension qui permet d’enregistrer IdentityServer dans le conteneur d’IoC.
La dépendance minimale dont nous avons besoin pour l’instant est AddDeveloperSigningCredential(). Cette extension permet de créer une clé temporaire et le nécessaire pour signer les jetons (Tokens). C’est pratique pour démarrer en environnement de développement. Mais, vous ne devez pas le laisser traîner là en production et vous devez fournir le nécessaire pour gérer cela.
Pour ajouter le middleware IdentityServer dans le pipeline HTTP de ASP.NET Core, vous devez modifier la méthode Configure() du fichier Startup.cs et ajouter la ligne de code suivante :
Code C# : | Sélectionner tout |
app.UseIdentityServer();
Le code complet de cette méthode est :
Code C# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIdentityServer(); app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } |
1-3 Configuration des clients et les ressources
Tout client qui fait appel à notre serveur de gestion d’identité doit être un client de confiance. C’est pourquoi ce dernier doit être référencé dans l’application IdentityServer.
Par ailleurs, toute ressource (API par exemple), donc l’accès est sécurisé, doit être répertoriée dans l’application IdentityServer.
Pour cela, nous allons créer une classe Config, qui aura une méthode GetClients, qui permettra de retourner la liste des clients supportés par l’application et une méthode GetApiResources, qui retournera la liste des APIs que nous voulons sécuriser l’accès. Pour l’instant, puisque nous n’avons pas encore développé nos clients et nos ressources, ces listes seront vides.
Vous devez donc ajouter un nouveau fichier Config.cs à votre application avec le code suivant :
Code C# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using IdentityServer4.Models; using System.Collections.Generic; namespace AspNetCoreIdentityServer { public class Config { public static IEnumerable<Client> GetClients() { return new List<Client> { }; } public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { }; } } } |
Une fois cela fait, vous devez éditer le fichier Startup.cs et modifier la méthode ConfigureServices pour configurer IdentityServer pour qu’il utilise la liste des clients et les ressources que nous avons définis :
Code C# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | public void ConfigureServices(IServiceCollection services) { //configure identity server with in-memory stores, keys, clients and resources services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()); } |
C’est tout. Nous venons de faire le minimum pour intégrer IdentityServer à notre projet. Nous pouvons désormais l’utiliser comme service de gestion sécurisée des accès pour nos applications.
Mais avant, nous allons faire quelques modifications pour nous assurer que les clients pointeront toujours sur la bonne application.
1-4 Modification de l’hôte
Nous devons nous assurer que notre application IdentityServer sera toujours accessible via la même adresse lorsqu’elle est en exécution. Par ailleurs, en environnement de développement et lorsqu’on est en mode apprentissage, il est intéressant de voir en temps réel les logs de notre application dans la console.
Pour cela, nous allons accéder à l’onglet « Déboguer » dans les propriétés de notre projet. Nous allons dérouler la zone « Profil » et sélectionner le nom de l'application (AspNetCoreIdentityServer).
Les URL suivantes doivent être définies dans le champ URL de l’application, si ce n’est pas le cas :
https://localhost:5001;http://localhost:5000
Générez et exécutez votre application.
NB : Les projets ASP.NET Core 2.1 sont configurés pour utiliser par défaut SSL. Pour éviter les avertissements SSL dans le navigateur, vous devez accepter le certificat auto-signé généré par ASP.NET Core. Une notification s’affichera à cet effet à la première exécution de votre application.
Ouvrez votre navigateur et saisissez l’adresse URL :
http://localhost:5000/.well-known/openid-configuration
ou
https://localhost:5001/.well-known/openid-configuration
Vous obtiendrez le résultat suivant :
Vous venez de mettre en place votre service de gestion sécurisée de jetons. Il est prêt pour la sécurisation de vos ressources et l’authentification de vos clients.