From 3b524fa29ecec61a5ecba156702e9d69966fd2a4 Mon Sep 17 00:00:00 2001 From: Siwa12100 Date: Sat, 13 Jan 2024 20:37:12 +0100 Subject: [PATCH] premiere version de l'authentification fonctionnelle ! :sparkles: --- VeraxShield/VeraxShield/App.razor | 21 +++++- VeraxShield/VeraxShield/Program.cs | 11 ++- VeraxShield/VeraxShield/_Imports.razor | 4 +- .../FormulaireConnexion.razor | 33 +++++++++ .../FormulaireConnexion.razor.cs | 43 +++++++++++ .../modele/RequeteConnexion.cs | 13 ++++ .../modele/RequeteInscription.cs | 17 +++++ .../modele/authentification/AppUtilisateur.cs | 25 +++++++ .../authentification/UtilisateurCourant.cs | 6 ++ VeraxShield/VeraxShield/pages/Index.razor | 12 ++- VeraxShield/VeraxShield/pages/Index.razor.cs | 23 ++++++ .../pages/authentification/Connexion.razor | 8 ++ .../utilisateurs/ListeUtilisateurs.razor | 5 +- .../AuthentificationService.cs | 51 +++++++++++++ .../authentificationService/DonneurEtat.cs | 74 +++++++++++++++++++ .../IAuthentificationService.cs | 8 ++ .../LayoutAuthentification.razor | 7 ++ 17 files changed, 354 insertions(+), 7 deletions(-) create mode 100644 VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor create mode 100644 VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor.cs create mode 100644 VeraxShield/VeraxShield/composants/authentification/modele/RequeteConnexion.cs create mode 100644 VeraxShield/VeraxShield/composants/authentification/modele/RequeteInscription.cs create mode 100644 VeraxShield/VeraxShield/modele/authentification/AppUtilisateur.cs create mode 100644 VeraxShield/VeraxShield/modele/authentification/UtilisateurCourant.cs create mode 100644 VeraxShield/VeraxShield/pages/Index.razor.cs create mode 100644 VeraxShield/VeraxShield/pages/authentification/Connexion.razor create mode 100644 VeraxShield/VeraxShield/services/authentificationService/AuthentificationService.cs create mode 100644 VeraxShield/VeraxShield/services/authentificationService/DonneurEtat.cs create mode 100644 VeraxShield/VeraxShield/services/authentificationService/IAuthentificationService.cs create mode 100644 VeraxShield/VeraxShield/shared/layouts/authentification/LayoutAuthentification.razor diff --git a/VeraxShield/VeraxShield/App.razor b/VeraxShield/VeraxShield/App.razor index 623580d..48e4e6f 100644 --- a/VeraxShield/VeraxShield/App.razor +++ b/VeraxShield/VeraxShield/App.razor @@ -1,4 +1,19 @@ - + + + + + + + +

Sorry, there's nothing at this address.

+
+
+
+
+ + + +@* @@ -9,4 +24,6 @@

Sorry, there's nothing at this address.

-
+
*@ + + diff --git a/VeraxShield/VeraxShield/Program.cs b/VeraxShield/VeraxShield/Program.cs index 9726563..eb1cf66 100644 --- a/VeraxShield/VeraxShield/Program.cs +++ b/VeraxShield/VeraxShield/Program.cs @@ -5,6 +5,7 @@ using Blazorise.Bootstrap; using Blazorise.Icons.FontAwesome; using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Web; using VeraxShield.services.UtilisateursDataService; @@ -12,11 +13,11 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); -// Ajout du client http par défaut : +// Ajout du client http par d�faut : builder.Services.AddHttpClient(); // Ajout du service de gestion des utilisateurs : -// On le met scoped, car c'est comme ça qu'est le service du localStorage alors sinon ça marche pas... +// On le met scoped, car c'est comme �a qu'est le service du localStorage alors sinon �a marche pas... builder.Services.AddScoped(); // Ajout du service pour le Blazored LocalStorage : @@ -31,6 +32,12 @@ builder.Services .AddBootstrapProviders() .AddFontAwesomeIcons(); +// Ajout de services pour l'authenfication : +builder.Services.AddOptions(); + builder.Services.AddAuthorizationCore(); + builder.Services.AddScoped(); + builder.Services.AddScoped(s => s.GetRequiredService()); + builder.Services.AddScoped(); var app = builder.Build(); diff --git a/VeraxShield/VeraxShield/_Imports.razor b/VeraxShield/VeraxShield/_Imports.razor index b4cb8e5..8d60b94 100644 --- a/VeraxShield/VeraxShield/_Imports.razor +++ b/VeraxShield/VeraxShield/_Imports.razor @@ -6,4 +6,6 @@ @using Blazored.LocalStorage @using Blazorise -@using Blazorise.DataGrid \ No newline at end of file +@using Blazorise.DataGrid + +@using Microsoft.AspNetCore.Components.Authorization \ No newline at end of file diff --git a/VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor b/VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor new file mode 100644 index 0000000..97098d6 --- /dev/null +++ b/VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor @@ -0,0 +1,33 @@ +@using Blazorise.Components; +@using System.ComponentModel.DataAnnotations; + +

Se connecter

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor.cs b/VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor.cs new file mode 100644 index 0000000..6930c04 --- /dev/null +++ b/VeraxShield/VeraxShield/composants/authentification/FormulaireConnexion.razor.cs @@ -0,0 +1,43 @@ + +using Blazorise; +using Microsoft.AspNetCore.Components; +using VeraxShield.composants.formulaires.modeles; + +namespace VeraxShield.composants.authentification +{ + public partial class FormulaireConnexion + { + [Parameter] + public Validations Validations {get; set;} + + public RequeteConnexion Requete {get; set;} + + [Inject] + private NavigationManager NavigationManager {get; set;} + + [Inject] + private DonneurEtat DonneurEtat {get; set;} + + public String Erreur {get; set; } + + protected override async Task OnInitializedAsync() + { + this.Requete = new RequeteConnexion(); + } + + public async Task OnSubmit() + { + if (await this.Validations.ValidateAll()) + { + try + { + await DonneurEtat.Connexion(this.Requete); + NavigationManager.NavigateTo("/"); + } catch (Exception ex) + { + this.Erreur = ex.Message; + } + } + } + } +} \ No newline at end of file diff --git a/VeraxShield/VeraxShield/composants/authentification/modele/RequeteConnexion.cs b/VeraxShield/VeraxShield/composants/authentification/modele/RequeteConnexion.cs new file mode 100644 index 0000000..f77a7c2 --- /dev/null +++ b/VeraxShield/VeraxShield/composants/authentification/modele/RequeteConnexion.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace VeraxShield.composants.formulaires.modeles +{ + public class RequeteConnexion + { + [Required] + public string MotDePasse { get; set; } + + [Required] + public string Nom { get; set; } + } +} diff --git a/VeraxShield/VeraxShield/composants/authentification/modele/RequeteInscription.cs b/VeraxShield/VeraxShield/composants/authentification/modele/RequeteInscription.cs new file mode 100644 index 0000000..0a80f0d --- /dev/null +++ b/VeraxShield/VeraxShield/composants/authentification/modele/RequeteInscription.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace VeraxShield.composants.formulaires.modeles +{ + public class RequeteInscription + { + [Required] + public string MotDePasse { get; set; } + + [Required] + [Compare(nameof(MotDePasse), ErrorMessage = "Les mots de passe diffèrent !")] + public string MotDePasseConfirmation { get; set; } + + [Required] + public string Nom { get; set; } + } +} diff --git a/VeraxShield/VeraxShield/modele/authentification/AppUtilisateur.cs b/VeraxShield/VeraxShield/modele/authentification/AppUtilisateur.cs new file mode 100644 index 0000000..4da82d2 --- /dev/null +++ b/VeraxShield/VeraxShield/modele/authentification/AppUtilisateur.cs @@ -0,0 +1,25 @@ +public class AppUtilisateur +{ + public string MotDePasse { get; set; } + public List Roles { get; set; } + public string Nom { get; set; } + + public AppUtilisateur(string nom, string mdp, String premierRole) + { + this.MotDePasse = mdp; + this.Nom = nom; + + this.Roles = new List(); + this.Roles.Add(premierRole); + } + + public void ajouterRole(string nouveauRole) + { + this.Roles.Add(nouveauRole); + } + + public void supprimerRole(string ancienRole) + { + this.Roles.Remove(ancienRole); + } +} \ No newline at end of file diff --git a/VeraxShield/VeraxShield/modele/authentification/UtilisateurCourant.cs b/VeraxShield/VeraxShield/modele/authentification/UtilisateurCourant.cs new file mode 100644 index 0000000..9cb4e08 --- /dev/null +++ b/VeraxShield/VeraxShield/modele/authentification/UtilisateurCourant.cs @@ -0,0 +1,6 @@ +public class UtilisateurCourant +{ + public Dictionary Claims { get; set; } + public bool EstAuthentifie { get; set; } + public string Nom { get; set; } +} \ No newline at end of file diff --git a/VeraxShield/VeraxShield/pages/Index.razor b/VeraxShield/VeraxShield/pages/Index.razor index 80ca94c..389d7ef 100644 --- a/VeraxShield/VeraxShield/pages/Index.razor +++ b/VeraxShield/VeraxShield/pages/Index.razor @@ -2,4 +2,14 @@

VeraxShield

- --> Liste des utilisateurs + + + + +

Adiu : @context.User.Identity.Name!

+

Podètz veire aquest contengut solament se sètz autentificat !

+ + --> Liste des utilisateurs + + +
diff --git a/VeraxShield/VeraxShield/pages/Index.razor.cs b/VeraxShield/VeraxShield/pages/Index.razor.cs new file mode 100644 index 0000000..0ed27c7 --- /dev/null +++ b/VeraxShield/VeraxShield/pages/Index.razor.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Components; + +namespace VeraxShield.pages +{ + public partial class Index + { + [Inject] + private DonneurEtat DonneurEtat {get; set;} + + [Inject] + private NavigationManager NavigationManager {get; set;} + private async Task SeDeconnecter() + { + await DonneurEtat.Deconnexion(); + NavigationManager.NavigateTo("/connexion"); + } + + private async Task SeConnecter() + { + NavigationManager.NavigateTo("/connexion"); + } + } +} \ No newline at end of file diff --git a/VeraxShield/VeraxShield/pages/authentification/Connexion.razor b/VeraxShield/VeraxShield/pages/authentification/Connexion.razor new file mode 100644 index 0000000..5dcc99d --- /dev/null +++ b/VeraxShield/VeraxShield/pages/authentification/Connexion.razor @@ -0,0 +1,8 @@ +@using VeraxShield.composants.authentification; + +@page "/connexion" + +

Page de connexion

+ + + diff --git a/VeraxShield/VeraxShield/pages/utilisateurs/ListeUtilisateurs.razor b/VeraxShield/VeraxShield/pages/utilisateurs/ListeUtilisateurs.razor index 5517f7e..060d0f7 100644 --- a/VeraxShield/VeraxShield/pages/utilisateurs/ListeUtilisateurs.razor +++ b/VeraxShield/VeraxShield/pages/utilisateurs/ListeUtilisateurs.razor @@ -1,6 +1,9 @@ -@using VeraxShield.composants.affichages.utilisateurs; +@using Microsoft.AspNetCore.Authorization +@using VeraxShield.composants.affichages.utilisateurs; @page "/utilisateurs/liste" +@attribute [Authorize(Roles = "admin, modo")] +

Utilisateurs de Verax

diff --git a/VeraxShield/VeraxShield/services/authentificationService/AuthentificationService.cs b/VeraxShield/VeraxShield/services/authentificationService/AuthentificationService.cs new file mode 100644 index 0000000..ea18e2f --- /dev/null +++ b/VeraxShield/VeraxShield/services/authentificationService/AuthentificationService.cs @@ -0,0 +1,51 @@ +using System.Security.Claims; +using VeraxShield.composants.formulaires.modeles; + +public class AuthentificationService : IAuthentificationService +{ + + private static readonly List utilisateursApplication; + + + + static AuthentificationService() + { + utilisateursApplication = new List(); + utilisateursApplication.Add(new AppUtilisateur("Admin", "Admin", "admin")); + } + + public void Connexion(RequeteConnexion requete) + { + var utilisateur = utilisateursApplication.FirstOrDefault(w => w.Nom == requete.Nom && w.MotDePasse == requete.MotDePasse); + + if (utilisateur == null) + { + throw new Exception("Pseudo ou mot de passe invalide ! "); + } + } + + public UtilisateurCourant GetUtilisateur(string nom) + { + var utilisateur = utilisateursApplication.FirstOrDefault(w => w.Nom == nom); + + if (utilisateur == null) + { + throw new Exception("Pseudo ou mot de passe invalide !"); + } + + var claims = new List(); + claims.AddRange(utilisateur.Roles.Select(s => new Claim(ClaimTypes.Role, s))); + + return new UtilisateurCourant + { + EstAuthentifie = true, + Nom = utilisateur.Nom, + Claims = claims.ToDictionary(c => c.Type, c => c.Value) + }; + } + + public void Inscription(RequeteInscription requete) + { + utilisateursApplication.Add(new AppUtilisateur(requete.Nom, requete.MotDePasse, "invite" )); + } +} \ No newline at end of file diff --git a/VeraxShield/VeraxShield/services/authentificationService/DonneurEtat.cs b/VeraxShield/VeraxShield/services/authentificationService/DonneurEtat.cs new file mode 100644 index 0000000..bb0af8a --- /dev/null +++ b/VeraxShield/VeraxShield/services/authentificationService/DonneurEtat.cs @@ -0,0 +1,74 @@ +using System.Security.Claims; +using Microsoft.AspNetCore.Components.Authorization; +using VeraxShield.composants.formulaires.modeles; + +public class DonneurEtat : AuthenticationStateProvider +{ + private IAuthentificationService _serviceAuthentification; + private UtilisateurCourant _utilisateurCourant; + + public DonneurEtat(IAuthentificationService service) + { + this._serviceAuthentification = service; + } + + public override Task GetAuthenticationStateAsync() + { + var identite = new ClaimsIdentity(); + + try + { + var userInfo = this.getUtilisateurCourant(); + + if (userInfo.EstAuthentifie) + { + var claims = new[] { new Claim(ClaimTypes.Name, this._utilisateurCourant.Nom) }.Concat(this._utilisateurCourant.Claims.Select(c => new Claim(c.Key, c.Value))); + identite = new ClaimsIdentity(claims, "Server authentication"); + } + } + catch (HttpRequestException ex) + { + Console.WriteLine("Request failed:" + ex); + } + + return Task.FromResult(new AuthenticationState(new ClaimsPrincipal(identite))); + } + + private UtilisateurCourant getUtilisateurCourant() + { + if (this._utilisateurCourant != null && this._utilisateurCourant.EstAuthentifie) + { + return this._utilisateurCourant; + } + + return new UtilisateurCourant(); + } + + public async Task Connexion(RequeteConnexion requete) + { + this._serviceAuthentification.Connexion(requete); + + // No error - Login the user + var user = this._serviceAuthentification.GetUtilisateur(requete.Nom); + this._utilisateurCourant = user; + + NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); + } + + public async Task Deconnexion() + { + this._utilisateurCourant = null; + NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); + } + + public async Task Inscription(RequeteInscription requete) + { + this._serviceAuthentification.Inscription(requete); + + // No error - Login the user + var user = this._serviceAuthentification.GetUtilisateur(requete.Nom); + this._utilisateurCourant = user; + + NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); + } +} \ No newline at end of file diff --git a/VeraxShield/VeraxShield/services/authentificationService/IAuthentificationService.cs b/VeraxShield/VeraxShield/services/authentificationService/IAuthentificationService.cs new file mode 100644 index 0000000..8fc7045 --- /dev/null +++ b/VeraxShield/VeraxShield/services/authentificationService/IAuthentificationService.cs @@ -0,0 +1,8 @@ +using VeraxShield.composants.formulaires.modeles; + +public interface IAuthentificationService +{ + public UtilisateurCourant GetUtilisateur(String nom); + public void Connexion(RequeteConnexion requete); + public void Inscription(RequeteInscription requete); +} \ No newline at end of file diff --git a/VeraxShield/VeraxShield/shared/layouts/authentification/LayoutAuthentification.razor b/VeraxShield/VeraxShield/shared/layouts/authentification/LayoutAuthentification.razor new file mode 100644 index 0000000..c9fd75a --- /dev/null +++ b/VeraxShield/VeraxShield/shared/layouts/authentification/LayoutAuthentification.razor @@ -0,0 +1,7 @@ +@inherits LayoutComponentBase + +
+
+ @Body +
+
\ No newline at end of file