Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Semaine 5

Cette semaine nous allons ajouter une couche de sécurité et d’authentification avec des tokens JWT.

Version du front : https://csharp.nouvet.fr/front5/

Authentification JWT

Référez-vous à la documentation sur l’authentification pour comprendre le fonctionnement des JWT et leur implémentation.

Résumé des étapes

  1. Installer le package Microsoft.AspNetCore.Authentication.JwtBearer
  2. Créer un service JwtService pour générer les tokens
  3. Configurer la validation JWT dans Program.cs
  4. Protéger les routes avec [Authorize]

Création du service JWT

Créez un nouveau fichier Services/JwtService.cs qui contiendra une méthode GenerateToken(User user) retournant un token JWT.

Le token doit contenir les claims suivants :

  • ClaimTypes.NameIdentifier : l’ID de l’utilisateur
  • ClaimTypes.Name : le nom d’utilisateur
  • ClaimTypes.Role : le rôle de l’utilisateur

Référez-vous à la section Générer un JWT pour l’implémentation.

Configuration dans Program.cs

Ajoutez la configuration de l’authentification JWT. Voir la section Valider un JWT.

N’oubliez pas d’ajouter le service en AddScoped dans le Program.cs.

Modification du UserController

Injection du service JWT

Injectez le JwtService dans le constructeur du contrôleur.

Modification des routes Login et Register

Les routes Login et Register doivent maintenant retourner un token en plus des informations de l’utilisateur :

var token = _jwtService.GenerateToken(user);
return Ok(new { token = token, user = UserPublic.FromUser(user) });

Ces routes doivent rester accessibles sans authentification avec [AllowAnonymous].

Protection des routes

Ajoutez [Authorize] au niveau du contrôleur. Voir la section Vérification de l’authentification.

Pour les routes sensibles réservées aux administrateurs, utilisez [Authorize(Roles = "Admin")] :

  • PUT /api/User/{id}
  • DELETE /api/User/{id}

Récupérer l’ID utilisateur depuis le token

Au lieu de passer le userId en paramètre de route, récupérez-le depuis le token. Voir la section Récupération de l’utilisateur.

Ajoutez cette méthode helper dans vos contrôleurs :

private int? GetUserId()
{
    var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier);
    if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out int userId))
    {
        return null;
    }
    return userId;
}

Modification des routes

GameController

Toutes les routes doivent être protégées et ne plus prendre le userId en paramètre :

Ancienne routeNouvelle route
GET /api/Game/Click/{userId}GET /api/Game/Click
GET /api/Game/Progression/{userId}GET /api/Game/Progression
GET /api/Game/Initialize/{userId}GET /api/Game/Initialize
POST /api/Game/Reset/{userId}POST /api/Game/Reset
GET /api/Game/ResetCost/{userId}GET /api/Game/ResetCost

Game Server API Documentation - Semaine 5

Toutes les routes protégées nécessitent le header Authorization avec le token JWT : Authorization: Bearer <token>

Base URL: http://localhost:5000/api


Tables des autorisations par contrôleur

UserController

RouteMéthodeAutorisation
/api/User/LoginPOSTPublic
/api/User/RegisterPOSTPublic
/api/User/{id}GET[Authorize]
/api/User/{id}PUT[Authorize(Roles = "Admin")]
/api/User/{id}DELETE[Authorize(Roles = "Admin")]
/api/User/AllGET[Authorize]
/api/User/AllAdminGET[Authorize(Roles = "Admin")]
/api/User/Search/{name}GET[Authorize]

GameController

RouteMéthodeAutorisation
/api/Game/ClickGET[Authorize]
/api/Game/ProgressionGET[Authorize]
/api/Game/InitializeGET[Authorize]
/api/Game/ResetPOST[Authorize]
/api/Game/ResetCostGET[Authorize]
/api/Game/BestScoreGET[Authorize]

InventoryController

RouteMéthodeAutorisation
/api/Inventory/SeedGETPublic
/api/Inventory/ItemsGETPublic
/api/Inventory/UserInventoryGET[Authorize]
/api/Inventory/Buy/{itemId}POST[Authorize]

Routes avec modification du retour

Login

POST /api/User/Login

Body:

{
  "username": "string",
  "password": "string"
}

Ancien retour: UserPublic

Nouveau retour:

{
  "token": "string",
  "user": UserPublic
}

Register

POST /api/User/Register

Body:

{
  "username": "string",
  "password": "string"
}

Ancien retour: UserPublic

Nouveau retour:

{
  "token": "string",
  "user": UserPublic
}