premiere version de l'authentification fonctionnelle !

testMotDePasse
Siwa12100 1 year ago
parent 9d2e07af6d
commit 3b524fa29e

@ -1,4 +1,19 @@
<Router AppAssembly="@typeof(App).Assembly">
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<CascadingAuthenticationState>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</CascadingAuthenticationState>
</NotFound>
</Router>
@* <Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
@ -9,4 +24,6 @@
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</Router> *@

@ -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<EFBFBD>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 <EFBFBD>a qu'est le service du localStorage alors sinon <20>a marche pas...
builder.Services.AddScoped<IUtilisateursDataService, UtilisateursDataServiceFactice>();
// 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<DonneurEtat>();
builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<DonneurEtat>());
builder.Services.AddScoped<IAuthentificationService, AuthentificationService>();
var app = builder.Build();

@ -7,3 +7,5 @@
@using Blazorise
@using Blazorise.DataGrid
@using Microsoft.AspNetCore.Components.Authorization

@ -0,0 +1,33 @@
@using Blazorise.Components;
@using System.ComponentModel.DataAnnotations;
<h1> Se connecter</h1>
<Validations @ref="Validations" Mode="ValidationMode.Auto" Model="Requete">
<Validation Validator="@ValidationRule.IsNotEmpty">
<Field>
<TextEdit Placeholder="Pseudo" @bind-Text="@Requete.Nom">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
<Validation Validator="@ValidationRule.IsNotEmpty">
<Field>
<TextEdit Placeholder="Mot de passe" @bind-Text="@Requete.MotDePasse">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
<Button Color="Color.Primary" Clicked="@OnSubmit">Connexion</Button>
<label class="text-danger">@Erreur</label>
</Validations>

@ -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;
}
}
}
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -0,0 +1,25 @@
public class AppUtilisateur
{
public string MotDePasse { get; set; }
public List<string> 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<string>();
this.Roles.Add(premierRole);
}
public void ajouterRole(string nouveauRole)
{
this.Roles.Add(nouveauRole);
}
public void supprimerRole(string ancienRole)
{
this.Roles.Remove(ancienRole);
}
}

@ -0,0 +1,6 @@
public class UtilisateurCourant
{
public Dictionary<string, string> Claims { get; set; }
public bool EstAuthentifie { get; set; }
public string Nom { get; set; }
}

@ -2,4 +2,14 @@
<h1>VeraxShield</h1>
<NavLink href="/utilisateurs/liste"> --> Liste des utilisateurs</NavLink>
<button type="button" class="btn btn-link ml-md-auto" @onclick="@SeConnecter">Connexion</button>
<AuthorizeView>
<h1> Adiu : @context.User.Identity.Name!</h1>
<p>Podètz veire aquest contengut solament se sètz autentificat ! </p>
<NavLink href="/utilisateurs/liste"> --> Liste des utilisateurs</NavLink>
<button type="button" class="btn btn-link ml-md-auto" @onclick="@SeDeconnecter">Deconnexion</button>
</AuthorizeView>

@ -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");
}
}
}

@ -0,0 +1,8 @@
@using VeraxShield.composants.authentification;
@page "/connexion"
<h1> Page de connexion </h1>
<FormulaireConnexion/>

@ -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")]
<h1>Utilisateurs de Verax</h1>
<DatagridUtilisateurs/>

@ -0,0 +1,51 @@
using System.Security.Claims;
using VeraxShield.composants.formulaires.modeles;
public class AuthentificationService : IAuthentificationService
{
private static readonly List<AppUtilisateur> utilisateursApplication;
static AuthentificationService()
{
utilisateursApplication = new List<AppUtilisateur>();
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<Claim>();
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" ));
}
}

@ -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<AuthenticationState> 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());
}
}

@ -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);
}

@ -0,0 +1,7 @@
@inherits LayoutComponentBase
<div class="main">
<div class="content px-4">
@Body
</div>
</div>
Loading…
Cancel
Save