Voir le flux RSS

Blog de Hinault Romaric (.NET Core, ASP.NET Core, Azure, DevOps)

[Actualité] IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect

Note : 3 votes pour une moyenne de 5,00.
par , 12/12/2018 à 02h03 (2576 Affichages)
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.


Ce billet est le quatrième que j’écris sur le sujet. Les billets précédents ont porté sur les points suivants :

Mise en place d’un STS avec IdentityServer4 pour sécuriser ses applications .NET

Sécurisation d’une Web API ASP.NET Core avec le STS IdentityServer4

IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée

Nous disposons d’une application Web dont nous voulons sécuriser certaines pages. Pour accéder à ces pages, l’utilisateur doit s’authentifier au préalable en utilisant son compte.
Nous devons donc intégrer cette nouvelle application à notre IdentityServer. Lorsque l’utilisateur vaudra accéder à une page protégée, il sera redirigé vers IdentityServer qui affichera une fenêtre d’authentification. Une fois ce dernier authentifié, il sera redirigé vers la page à laquelle il voulait accéder.

Ajout de l’interface d’authentification

Actuellement notre solution IdentityServer ne dispose d’aucune interface. Tout ce qu’elle est en mesure d’afficher dans un navigateur c’est un « Hello World! ».

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
 
            }
 
            app.UseIdentityServer();
 
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

Elle ne dispose donc d’aucune vue, aucun contrôleur, etc. Pourtant, nous avons besoin d’une solution permettant d’authentifier un utilisateur via un formulaire, mettre fin à sa session, etc. Pour mettre cela en place, nous allons nous appuyer sur un modèle Quickstart existant fourni par les développeurs de IdentityServer4.

Ce modèle est disponible dans le repository GitHub suivant https://github.com/IdentityServer/Id.../release/Views. Vous pouvez le télécharger et copier/coller les dossiers Quickstart, Views et wwwroot dans votre projet.

Vous pouvez aussi simplement ouvrir le terminal Powershell dans le dossier racine du projet et exécuter la commande :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.ps1'))
Je n’entrerais pas dans les détails d’implémentation de ce modèle.

Transformation du projet en solution MVC

Le Quickstart que nous avons intégré repose sur ASP.NET MVC. Nous allons apporter quelques modifications à notre projet pour prendre en charge ASP.NET Core MVC.

La première chose à faire sera de modifier la méthode ConfigureServices() et ajouter la ligne de code suivante au début :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Cette ligne de code permet d’enregistrer les services pour la prise en charge de ASP.NET Core MVC.

Par la suite, vous devez modifier la méthode Configure pour intégrer les middlewares nécessaires à la gestion des fichiers statistiques et le routage. Par ailleurs, vous devez supprimer la ligne de code permettant d’afficher le « Hello Word! » :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
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.UseStaticFiles();
 
            app.UseIdentityServer();
 
            app.UseMvcWithDefaultRoute();
        }

Ajout du support pour OpenID Connect

OpenID Connect est une couche d'identification basée sur le protocole OAuth 2.0, qui autorise les clients à vérifier l'identité d'un utilisateur final en se basant sur l'authentification fournie par un serveur d'autorisation, dont IdentityServer. L’authentification d’un utilisateur via un formulaire avec IdentityServer repose sur OpenID Connect.

L’implémentation utilise le concept de scopes (portés). Nous devons définir comme nous l’avons fait précédemment pour l’API les ressources auxquelles le client doit accéder. Sauf qu’ici, il s’agit des informations du profil utilisateur (id, nom, email, etc.) que nous souhaitons partager avec le client. Ces ressources sont donc de type IdentityResources.

Pour le faire, nous allons éditer le fichier Config.cs et ajouter les lignes de code suivantes :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
    };
}

Une fois cela fait, nous devons modifier la méthode ConfigureServices du fichier Startup.cs pour ajouter cette nouvelle ressource à la configuration d’IdentityServer. Cela se fait en utilisant la méthode d’extension AddInMemoryIdentityResources :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 
            //configure identity server with in-memory stores, keys, clients and resources
            services.AddIdentityServer()
                   .AddDeveloperSigningCredential()
                   .AddInMemoryIdentityResources(Config.GetIdentityResources())
                    .AddInMemoryApiResources(Config.GetApiResources())
                   .AddInMemoryClients(Config.GetClients());
 
        }

Ajout des utilisateurs pour les tests

Les informations saisies par l’utilisateur dans le formulaire d’authentification doivent être validées avant de lui donner les accès. Cependant nous ne disposons pas d’une base de données des utilisateurs que nous pouvons utiliser. IdentityServer pour des besoins de tests permet de définir et utiliser une liste de type TestUser.

Nous allons une nouvelle fois modifier le fichier Config.cs et ajouter le code suivant pour définir notre liste d’utilisateurs avec leurs revendications (claims):

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
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
26
27
28
29
30
31
 public static List<TestUser> GetUsers()
        {
            return new List<TestUser>
            {
                new TestUser{SubjectId = "818727", Username = "alice", Password = "alice",
                Claims =
                {
                    new Claim(JwtClaimTypes.Name, "Alice Smith"),
                    new Claim(JwtClaimTypes.GivenName, "Alice"),
                    new Claim(JwtClaimTypes.FamilyName, "Smith"),
                    new Claim(JwtClaimTypes.Email, "AliceSmith@email.com"),
                    new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
                    new Claim(JwtClaimTypes.WebSite, "http://alice.com"),
                    new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json)
                }
            },
            new TestUser{SubjectId = "88421113", Username = "bob", Password = "bob",
                Claims =
                {
                    new Claim(JwtClaimTypes.Name, "Bob Smith"),
                    new Claim(JwtClaimTypes.GivenName, "Bob"),
                    new Claim(JwtClaimTypes.FamilyName, "Smith"),
                    new Claim(JwtClaimTypes.Email, "BobSmith@email.com"),
                    new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
                    new Claim(JwtClaimTypes.WebSite, "http://bob.com"),
                    new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json),
                    new Claim("location", "somewhere")
                }
            }
            };
        }

Nous devons également modifier la méthode ConfigureServices du fichier Startup.cs pour ajouter cette liste à la configuration d’IdentityServer. Cela se fait en utilisant la méthode d’extension AddTestUsers lors de l’appel de AddIdentityServer() :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 
            //configure identity server with in-memory stores, keys, clients and resources
            services.AddIdentityServer()
                   .AddDeveloperSigningCredential()
                   .AddInMemoryIdentityResources(Config.GetIdentityResources())
                    .AddInMemoryApiResources(Config.GetApiResources())
                   .AddInMemoryClients(Config.GetClients())
                   .AddTestUsers(Config.GetUsers()); ;
 
        }

Enregistrez les modifications et exécutez l’application. Vous aurez le résultat suivant affiché dans le navigateur :

Nom : img12.PNG
Affichages : 2410
Taille : 24,0 Ko

Si vous cliquez sur « Click here to manage your stored grants. », vous essayerez d’accéder à une page protégée. De ce fait, vous serez redirigé vers la page d’authentification :

Nom : img13.PNG
Affichages : 2421
Taille : 13,0 Ko

Vous venez de mettre en place une interface d’authentification en utilisant OpenID Connect. Dans le prochain billet, nous verrons comment configurer une application Web pour utiliser cette nouvelle fonctionnalité que nous avons intégrée à IdentityServer pour valider l’identité d’un utilisateur.

Restez connecté !

Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog Viadeo Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog Twitter Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog Google Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog Facebook Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog Digg Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog Delicious Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog MySpace Envoyer le billet « IdentityServer4 : Authentification d’un utilisateur avec OpenID Connect » dans le blog Yahoo

Mis à jour 12/12/2018 à 09h53 par Malick

Catégories
DotNET , C# , .NET Core , ASP.NET Core

Commentaires

  1. Avatar de tomlev
    • |
    • permalink
    Bon à savoir : IdentityServer s'intègre aussi très bien avec ASP.NET Core Identity (il suffit de faire un petit .AddAspNetIdentity() sur la conf d'IdentityServer)
  2. Avatar de Eric80
    • |
    • permalink
    Merci pour cette bonne série d articles sur la sécurité avec Azure, pt important pour bcp d entreprises!

    Suggestion pour un prochain article sur le sujet, si pas déjà 'in the pipeline': comment sécuriser les connexions entre noeuds Dockers dans un cluster Kubernetes? Que cela soit avec SSL, IdentityServer4, etc?

    Quelques pistes:
    https://www.hanselman.com/blog/Setti...InMinutes.aspx
    https://stackoverflow.com/questions/...ubernetes?rq=1
    https://stackoverflow.com/questions/...erver4-service
  3. Avatar de stan92
    • |
    • permalink
    Merci pour ce tuto..tip top..

    J'ai une question qui me prends un peu la tête et je n'arrive pas à piger la chose.

    J'aimerais savoir s'il est possible d'affecter des utilisateurs à des "Applis" (des clients pour IIS) ?
    En d'autres termes, si j'ai deux applis MVC et une SPA, est il possible d'octroyer les droits d'accès à l'utilisateur U1 à l'ensemble des applis et à l'utilisateur U2 que l'accès à la SPA ?

    La réponse peut être "triviale" mais je reste preneur

    Et merci pour tout.
  4. Avatar de mictif
    • |
    • permalink
    Merci pour toutes ces explication détaillées !

    Pi : le liens vers les views n'est plus bon -> https://github.com/IdentityServer/Id....Quickstart.UI