IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

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

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

Note : 2 votes pour une moyenne de 5,00.
par , 21/10/2018 à 20h16 (6586 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.


Dans le premier billet de blog que j'ai rédigé sur le sujet, j'ai présenté comment mettre en place un serveur de gestion sécurisée de jetons (STS – Secure Token Service) en utilisant IdentityServer4. Dans le deuxième billet, nous avons vu comment sécuriser l’accès à une Web API ASP.NET Core en utilisant notre serveur Identityserver4.

Dans ce billet, nous allons créer le client qui sera une application Console .NET Core. Nous allons écrire le code nécessaire pour permettre à ce denier de demander un jeton de sécurité à l’application IdentityServer, ensuite utiliser ce dernier pour s’authentifier auprès de l’API et accéder à ses fonctionnalités.

1. Création du client

Pour commencer, nous allons créer une nouvelle application console .NET Core 2.x :


Nom : img7.PNG
Affichages : 6074
Taille : 30,8 Ko

Ensuite, nous devons ajouter le package Newtonsoft.Json à cette dernière en utilisant le gestionnaire de packages NuGet.

Nom : img8.PNG
Affichages : 5787
Taille : 64,9 Ko

Une fois cela fait, nous allons éditer le fichier Program.cs et ajouter le code nécessaire pour appeler notre API. Le code complet de la classe Program est le suivant :

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
class Program
    {
        static void Main(string[] args) => CallWebApi().GetAwaiter().GetResult();
 
        static async Task CallWebApi()
 
        {
            var client = new HttpClient();
 
            var response = await client.GetAsync("https://localhost:5003/api/secure");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }
        }
    }

Enregistrez et exécutez votre application.

Vous aurez le message suivant à l’écran :

Nom : img9.PNG
Affichages : 5474
Taille : 6,4 Ko

L’accès à la ressource pour notre application a été refusé. Nous allons maintenant configurer cette dernière pour qu’elle demande un jeton d’authentification à IdentityServer et qu’elle utilise ce dernier pour accéder à l’API.

2. Configuration du client

Pour accéder facilement à IdentityServer dans notre client, nous allons utiliser la librairie IdentityModel. La première chose à faire sera donc l’ajout du package correspondant à notre application en utilisant NuGet :

Nom : img10.PNG
Affichages : 5366
Taille : 69,3 Ko

Nous allons utiliser la méthode GetAsync() de la classe DiscoveryClient pour récupérer les métadonnées exposées par le EndPoint de l’application IdentityServer. Cette méthode prend en paramètre l’URL de notre application IdentityServer. Nous devons nous assurer que le EndPoint est accessible avant de continuer :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
var disco = await DiscoveryClient.GetAsync("https://localhost:5001");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }

Ensuite, nous devons initialiser un nouvel objet TokenClient, en lui passant en paramètre le TokenEndpoint, l’ID du client et le secret.
Nous allons utiliser la méthode RequestClientCredentialsAsync pour demander un jeton d’authentification pour accéder à l’API. Cette méthode prend en paramètre le nom de l’API auquel on veut accéder, tel qu’il est répertorié auprès de IdentityServer. Nous devons nous assurer que le jeton a été obtenu avant de continuer :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
// request token
            var tokenClient = new TokenClient(disco.TokenEndpoint, "consoleappclient", "secret");
            var tokenResponse = await tokenClient.RequestClientCredentialsAsync("testapi");
 
            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }
 
            Console.WriteLine(tokenResponse.Json);

Nous allons pour finir utiliser la méthode SetBearerToken de HttpClient() pour inscrire le jeton dans l’entête HTTP de notre requête :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
  var client = new HttpClient();
            client.SetBearerToken(tokenResponse.AccessToken);

Le code complet de la méthode CallWebApi devient ceci :

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
32
33
34
35
36
37
38
static async Task CallWebApi()
 
        {
            // discover endpoints from metadata
            var disco = await DiscoveryClient.GetAsync("https://localhost:5001");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }
 
            // request token
            var tokenClient = new TokenClient(disco.TokenEndpoint, "consoleappclient", "secret");
            var tokenResponse = await tokenClient.RequestClientCredentialsAsync("testapi");
 
            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }
 
            Console.WriteLine(tokenResponse.Json);
 
            // call api
            var client = new HttpClient();
            client.SetBearerToken(tokenResponse.AccessToken);
 
            var response = await client.GetAsync("https://localhost:5003/api/secure");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }
        }

3. Mise à jour de IdentityServer pour reconnaître le client

Toute la configuration nécessaire pour accéder à l’API a été effectuée côté client. Toutefois, si ce dernier essaye d’accéder à la ressource, il n’aura toujours pas le droit. Cela est dû au fait qu’il n’est pas encore connu par IdentityServer. Nous devons donc enregistrer ce dernier et définir à quoi il a accès.

Pour cela, nous devons éditer le fichier Config.cs et ajouter un nouveau client à la liste des clients. Nous devons lui donner le même nom et le même secret que nous avons passé en paramètre en initialisant le tokenclient dans l’application console :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
var tokenClient = new TokenClient(disco.TokenEndpoint, "consoleappclient", "secret");

Le code de la méthode GetClients de la classe Config devrait donc ressembler à ceci :

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
  public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
 
                new Client
                {
                    ClientId = "consoleappclient",
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
 
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes = { "testapi" }
                }
 
           };
        }

Vous remarquerez que nous avons également défini la ressource à laquelle le client doit accéder.

Enregistrez les modifications. Exécutez l’application IdentityServer, l’API et enfin l’application console.

Vous aurez le résultat suivant :

Nom : img11.PNG
Affichages : 5557
Taille : 25,8 Ko

Le jeton qui est généré par IdentityServer et utilisé par le client pour accéder à la ressource est au format JWT. Il s’agit d’un jeton sécurisé qui contient toutes les informations nécessaires pour confirmer l’identité du client et lui donner accès à la ressource demandée. Si vous décodez le jeton avec https://jwt.io, vous obtiendrez ce qui suit :

Nom : img11-0.PNG
Affichages : 5565
Taille : 107,1 Ko

Nous venons d’accéder à notre ressource sécurisée en utilisant un jeton de sécurité provenant d’IdentityServer.

Dans la prochain billet sur IdentityServer, nous verrons comment mettre en place l’authentification pour une application ASP.NET Core MVC en utilisant OpenID Connect.

Restez connecté !

Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog Viadeo Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog Twitter Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog Google Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog Facebook Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog Digg Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog Delicious Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog MySpace Envoyer le billet « IdentityServer4 : création et configuration du Client pour accéder à une Web API ASP.NET Core sécurisée » dans le blog Yahoo

Mis à jour 22/10/2018 à 15h51 par Malick

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

Commentaires

  1. Avatar de xiopian
    • |
    • permalink
    Très bon tutoriel, il m'a bien servit je galérais un peu mettre IdentityServer en place.

    Par contre juste une remarque pour d'autres car je me suis fait avoir, pour la package "IdentityModel" il ne faut pas mettre la V4.0.0 mais rester en V3.X.X !

    Et sinon est-ce qu'il est prévu d'autres tuto pour se connecter à des serveur Facebook, Outlook ou autres ?

    Bon dev
  2. Avatar de spriatez
    • |
    • permalink
    Super tutoriel, jusqu'ici je n'ai presque eu aucun soucis.

    Néanmoins arrivé à cette étape là, le DiscoveryClient est impossible à trouver ! Quelle dépendance ?
    De plus, TokenClient m'informer une surcharge, qu'il veut seulement 2 paramètres .. Même ne passant par les options ça ne fonctionne pas.. Dommage