Terminé ce projet « # Système de Gestion des Utilisateurs avec Sessions
et Cookies
## Étape 1 : Extension de la base de données
### Script SQL pour les utilisateurs et profils
```sql
USE GestionEtudiants ;
GO
Créer la table des profils/rôles
CREATE TABLE Profils (
Id INT IDENTITY(1,1) PRIMARY KEY,
NomProfil NVARCHAR(50) NOT NULL UNIQUE,
Description NVARCHAR(200),
DateCreation DATETIME DEFAULT GETDATE()
);
Créer la table des utilisateurs
CREATE TABLE Utilisateurs (
Id INT IDENTITY(1,1) PRIMARY KEY,
NomUtilisateur NVARCHAR(50) NOT NULL UNIQUE,
Email NVARCHAR(100) NOT NULL UNIQUE,
MotDePasse NVARCHAR(255) NOT NULL, -- Hash du mot de passe
Nom NVARCHAR(50) NOT NULL,
Prenom NVARCHAR(50) NOT NULL,
ProfilId INT NOT NULL,
EstActif BIT DEFAULT 1,
DateCreation DATETIME DEFAULT GETDATE(),
DerniereConnexion DATETIME NULL,
FOREIGN KEY (ProfilId) REFERENCES Profils(Id)
);
Insérer les profils par défaut
INSERT INTO Profils (NomProfil, Description) VALUES
(‘Administrateur’, ‘Accès complet au système, peut gérer les utilisateurs et
étudiants’),
(‘Gestionnaire’, ‘Peut gérer les étudiants mais pas les utilisateurs’) ;
Insérer des utilisateurs par défaut (mot de passe : « admin123 » et
« user123 » hashés en MD5 pour cet exemple)
INSERT INTO Utilisateurs (NomUtilisateur, Email, MotDePasse, Nom,
Prenom, ProfilId) VALUES
(‘admin’, ‘[email protected]’,
‘0192023A7BBD73250516F069DF18B500’, ‘Admin’, ‘Système’, 1), --
admin123
(‘gestionnaire’, ‘[email protected]’,
‘E10ADC3949BA59ABBE56E057F20F883E’, ‘Dupont’, ‘Jean’, 2) ; -- user123
Table pour gérer les sessions actives
CREATE TABLE SessionsActives (
Id INT IDENTITY(1,1) PRIMARY KEY,
SessionId NVARCHAR(128) NOT NULL,
UtilisateurId INT NOT NULL,
DateDebut DATETIME DEFAULT GETDATE(),
DateExpiration DATETIME NOT NULL,
AdresseIP NVARCHAR(45),
UserAgent NVARCHAR(500),
EstActive BIT DEFAULT 1,
FOREIGN KEY (UtilisateurId) REFERENCES Utilisateurs(Id)
);
GO
```
## Étape 2 : Modèles pour les utilisateurs
### Créer Models/Utilisateur.cs
```csharp
Using System ;
Using System.ComponentModel.DataAnnotations ;
Namespace GestionEtudiants.Models
Public class Utilisateur
Public int Id { get ; set ; }
[Required(ErrorMessage = « Le nom d’utilisateur est obligatoire »)]
[StringLength(50, ErrorMessage = « Le nom d’utilisateur ne peut pas
dépasser 50 caractères »)]
Public string NomUtilisateur { get ; set ; }
[Required(ErrorMessage = « L’email est obligatoire »)]
[EmailAddress(ErrorMessage = « Format d’email invalide »)]
[StringLength(100, ErrorMessage = « L’email ne peut pas dépasser
100 caractères »)]
Public string Email { get ; set ; }
[Required(ErrorMessage = « Le mot de passe est obligatoire »)]
[StringLength(255)]
Public string MotDePasse { get ; set ; }
[Required(ErrorMessage = « Le nom est obligatoire »)]
[StringLength(50, ErrorMessage = « Le nom ne peut pas dépasser 50
caractères »)]
Public string Nom { get ; set ; }
[Required(ErrorMessage = « Le prénom est obligatoire »)]
[StringLength(50, ErrorMessage = « Le prénom ne peut pas dépasser
50 caractères »)]
Public string Prenom { get ; set ; }
[Required(ErrorMessage = « Le profil est obligatoire »)]
Public int ProfilId { get ; set ; }
Public bool EstActif { get ; set ; }
Public DateTime DateCreation { get ; set ; }
Public DateTime ? DerniereConnexion { get ; set ; }
// Navigation properties
Public Profil Profil { get ; set ; }
Public string NomComplet
Get { return $ »{Prenom} {Nom} » ; }
}
}
```
### Créer Models/Profil.cs
```csharp
Using System ;
Using System.ComponentModel.DataAnnotations ;
Namespace GestionEtudiants.Models
Public class Profil
Public int Id { get ; set ; }
[Required(ErrorMessage = « Le nom du profil est obligatoire »)]
[StringLength(50, ErrorMessage = « Le nom du profil ne peut pas
dépasser 50 caractères »)]
Public string NomProfil { get ; set ; }
[StringLength(200, ErrorMessage = « La description ne peut pas
dépasser 200 caractères »)]
Public string Description { get ; set ; }
Public DateTime DateCreation { get ; set ; }
```
### Créer Models/SessionActive.cs
```csharp
Using System ;
Namespace GestionEtudiants.Models
Public class SessionActive
Public int Id { get ; set ; }
Public string SessionId { get ; set ; }
Public int UtilisateurId { get ; set ; }
Public DateTime DateDebut { get ; set ; }
Public DateTime DateExpiration { get ; set ; }
Public string AdresseIP { get ; set ; }
Public string UserAgent { get ; set ; }
Public bool EstActive { get ; set ; }
// Navigation property
Public Utilisateur Utilisateur { get ; set ; }
```
## Étape 3 : Couche d’accès aux données pour les utilisateurs
### Créer DAL/UtilisateurDAL.cs
```csharp
Using System ;
Using System.Collections.Generic ;
Using System.Configuration ;
Using System.Data ;
Using System.Data.SqlClient ;
Using System.Security.Cryptography ;
Using System.Text ;
Using GestionEtudiants.Models ;
Namespace GestionEtudiants.DAL
Public class UtilisateurDAL
Private readonly string connectionString ;
Public UtilisateurDAL()
connectionString =
ConfigurationManager.ConnectionStrings[« DefaultConnection »].Connecti
onString ;
// Authentification utilisateur
Public Utilisateur Authentifier(string nomUtilisateur, string
motDePasse)
Try
String motDePasseHash = HashMotDePasse(motDePasse) ;
Using (SqlConnection connection = new
SqlConnection(connectionString))
String query = @ »SELECT u.*, p.NomProfil, p.Description
FROM Utilisateurs u
INNER JOIN Profils p ON u.ProfilId = p.Id
WHERE u.NomUtilisateur = @NomUtilisateur
AND u.MotDePasse = @MotDePasse
AND u.EstActif = 1 » ;
Using (SqlCommand command = new SqlCommand(query,
connection))
Command.Parameters.AddWithValue(« @NomUtilisateur »,
nomUtilisateur) ;
Command.Parameters.AddWithValue(« @MotDePasse »,
motDePasseHash) ;
Connection.Open() ;
Using (SqlDataReader reader = command.ExecuteReader())
If (reader.Read())
Return new Utilisateur
Id = Convert.ToInt32(reader[« Id »]),
NomUtilisateur =
reader[« NomUtilisateur »].ToString(),
Email = reader[« Email »].ToString(),
Nom = reader[« Nom »].ToString(),
Prenom = reader[« Prenom »].ToString(),
ProfilId = Convert.ToInt32(reader[« ProfilId »]),
EstActif = Convert.ToBoolean(reader[« EstActif »]),
DateCreation =
Convert.ToDateTime(reader[« DateCreation »]),
DerniereConnexion =
reader[« DerniereConnexion »] as DateTime ?,
Profil = new Profil
Id = Convert.ToInt32(reader[« ProfilId »]),
NomProfil = reader[« NomProfil »].ToString(),
Description = reader[« Description »].ToString()
};
Catch (Exception)
// Log l’erreur
Return null ;
// Créer un utilisateur
Public bool CreerUtilisateur(Utilisateur utilisateur, string motDePasse)
Try
{
Using (SqlConnection connection = new
SqlConnection(connectionString))
String query = @ »INSERT INTO Utilisateurs (NomUtilisateur,
Email, MotDePasse, Nom, Prenom, ProfilId, EstActif)
VALUES (@NomUtilisateur, @Email, @MotDePasse,
@Nom, @Prenom, @ProfilId, @EstActif) » ;
Using (SqlCommand command = new SqlCommand(query,
connection))
Command.Parameters.AddWithValue(« @NomUtilisateur »,
utilisateur.NomUtilisateur) ;
Command.Parameters.AddWithValue(« @Email »,
utilisateur.Email) ;
Command.Parameters.AddWithValue(« @MotDePasse »,
HashMotDePasse(motDePasse)) ;
Command.Parameters.AddWithValue(« @Nom »,
utilisateur.Nom) ;
Command.Parameters.AddWithValue(« @Prenom »,
utilisateur.Prenom) ;
Command.Parameters.AddWithValue(« @ProfilId »,
utilisateur.ProfilId) ;
Command.Parameters.AddWithValue(« @EstActif »,
utilisateur.EstActif) ;
Connection.Open() ;
Int result = command.ExecuteNonQuery() ;
Return result > 0 ;
}
Catch (Exception)
Return false ;
// Obtenir tous les utilisateurs
Public List<Utilisateur> ObtenirTousLesUtilisateurs()
List<Utilisateur> utilisateurs = new List<Utilisateur>() ;
Try
Using (SqlConnection connection = new
SqlConnection(connectionString))
String query = @ »SELECT u.*, p.NomProfil, p.Description
FROM Utilisateurs u
INNER JOIN Profils p ON u.ProfilId = p.Id
ORDER BY u.Nom, u.Prenom » ;
Using (SqlCommand command = new SqlCommand(query,
connection))
Connection.Open() ;
Using (SqlDataReader reader = command.ExecuteReader())
While (reader.Read())
Utilisateurs.Add(new Utilisateur
{
Id = Convert.ToInt32(reader[« Id »]),
NomUtilisateur =
reader[« NomUtilisateur »].ToString(),
Email = reader[« Email »].ToString(),
Nom = reader[« Nom »].ToString(),
Prenom = reader[« Prenom »].ToString(),
ProfilId = Convert.ToInt32(reader[« ProfilId »]),
EstActif = Convert.ToBoolean(reader[« EstActif »]),
DateCreation =
Convert.ToDateTime(reader[« DateCreation »]),
DerniereConnexion =
reader[« DerniereConnexion »] as DateTime ?,
Profil = new Profil
Id = Convert.ToInt32(reader[« ProfilId »]),
NomProfil = reader[« NomProfil »].ToString(),
Description = reader[« Description »].ToString()
}) ;
Catch (Exception)
// Log l’erreur
}
Return utilisateurs ;
// Obtenir utilisateur par ID
Public Utilisateur ObtenirUtilisateurParId(int id)
Try
Using (SqlConnection connection = new
SqlConnection(connectionString))
String query = @ »SELECT u.*, p.NomProfil, p.Description
FROM Utilisateurs u
INNER JOIN Profils p ON u.ProfilId = p.Id
WHERE u.Id = @Id » ;
Using (SqlCommand command = new SqlCommand(query,
connection))
Command.Parameters.AddWithValue(« @Id », id) ;
Connection.Open() ;
Using (SqlDataReader reader = command.ExecuteReader())
If (reader.Read())
Return new Utilisateur
Id = Convert.ToInt32(reader[« Id »]),
NomUtilisateur =
reader[« NomUtilisateur »].ToString(),
Email = reader[« Email »].ToString(),
Nom = reader[« Nom »].ToString(),
Prenom = reader[« Prenom »].ToString(),
ProfilId = Convert.ToInt32(reader[« ProfilId »]),
EstActif = Convert.ToBoolean(reader[« EstActif »]),
DateCreation =
Convert.ToDateTime(reader[« DateCreation »]),
DerniereConnexion =
reader[« DerniereConnexion »] as DateTime ?,
Profil = new Profil
Id = Convert.ToInt32(reader[« ProfilId »]),
NomProfil = reader[« NomProfil »].ToString(),
Description = reader[« Description »].ToString()
};
Catch (Exception)
// Log l’erreur
Return null ;
}
// Mettre à jour la dernière connexion
Public void MettreAJourDerniereConnexion(int utilisateurId)
Try
Using (SqlConnection connection = new
SqlConnection(connectionString))
String query = « UPDATE Utilisateurs SET DerniereConnexion
= @DerniereConnexion WHERE Id = @Id » ;
Using (SqlCommand command = new SqlCommand(query,
connection))
Command.Parameters.AddWithValue(« @Id »,
utilisateurId) ;
Command.Parameters.AddWithValue(« @DerniereConnexion »,
DateTime.Now) ;
Connection.Open() ;
Command.ExecuteNonQuery() ;
Catch (Exception)
// Log l’erreur
}
// Obtenir tous les profils
Public List<Profil> ObtenirTousLesProfils()
List<Profil> profils = new List<Profil>() ;
Try
Using (SqlConnection connection = new
SqlConnection(connectionString))
String query = « SELECT * FROM Profils ORDER BY
NomProfil » ;
Using (SqlCommand command = new SqlCommand(query,
connection))
Connection.Open() ;
Using (SqlDataReader reader = command.ExecuteReader())
While (reader.Read())
Profils.Add(new Profil
Id = Convert.ToInt32(reader[« Id »]),
NomProfil = reader[« NomProfil »].ToString(),
Description = reader[« Description »] ?.ToString(),
DateCreation =
Convert.ToDateTime(reader[« DateCreation »])
}) ;
}
Catch (Exception)
// Log l’erreur
Return profils ;
// Hash du mot de passe (MD5 pour simplifier – en production utilisez
bcrypt ou Argon2)
Private string HashMotDePasse(string motDePasse)
Using (MD5 md5 = MD5.Create())
Byte[] inputBytes = Encoding.ASCII.GetBytes(motDePasse) ;
Byte[] hashBytes = md5.ComputeHash(inputBytes) ;
StringBuilder sb = new StringBuilder() ;
For (int i = 0 ; i < hashBytes.Length ; i++)
Sb.Append(hashBytes[i].ToString(« X2 »)) ;
Return sb.ToString() ;
}
}
```
## Étape 4 : Gestionnaire de sessions
### Créer Utils/SessionManager.cs
```csharp
Using System ;
Using System.Configuration ;
Using System.Data.SqlClient ;
Using System.Web ;
Using GestionEtudiants.Models ;
Namespace GestionEtudiants.Utils
Public static class SessionManager
Private const string SESSION_USER_KEY = « UtilisateurConnecte » ;
Private const string COOKIE_REMEMBER_KEY = « RememberUser » ;
Private const int SESSION_TIMEOUT_MINUTES = 30 ;
Private static readonly string connectionString =
ConfigurationManager.ConnectionStrings[« DefaultConnection »].Connecti
onString ;
// Créer une session utilisateur
Public static void CreerSession(Utilisateur utilisateur, bool
seRappelerDeMoi = false)
// Stocker l’utilisateur en session
HttpContext.Current.Session[SESSION_USER_KEY] = utilisateur ;
HttpContext.Current.Session.Timeout =
SESSION_TIMEOUT_MINUTES ;
// Enregistrer la session en base de données
EnregistrerSessionEnBDD(utilisateur.Id) ;
// Créer un cookie si « Se rappeler de moi » est coché
If (seRappelerDeMoi)
CreerCookieRappel(utilisateur.Id) ;
// Obtenir l’utilisateur connecté
Public static Utilisateur ObtenirUtilisateurConnecte()
If (HttpContext.Current.Session[SESSION_USER_KEY] != null)
Return
(Utilisateur)HttpContext.Current.Session[SESSION_USER_KEY] ;
// Vérifier si un cookie existe
Return VerifierCookieRappel() ;
}
// Vérifier si un utilisateur est connecté
Public static bool EstConnecte()
Return ObtenirUtilisateurConnecte() != null ;
// Vérifier si l’utilisateur a un profil spécifique
Public static bool AProfil(string nomProfil)
Var utilisateur = ObtenirUtilisateurConnecte() ;
Return utilisateur ?.Profil ?.NomProfil == nomProfil ;
// Vérifier si l’utilisateur est administrateur
Public static bool EstAdministrateur()
Return AProfil(« Administrateur ») ;
// Vérifier si l’utilisateur est gestionnaire
Public static bool EstGestionnaire()
Return AProfil(« Gestionnaire ») || EstAdministrateur() ;
// Déconnecter l’utilisateur
Public static void Deconnecter()
{
Var utilisateur = ObtenirUtilisateurConnecte() ;
If (utilisateur != null)
// Supprimer la session de la BDD
SupprimerSessionBDD(HttpContext.Current.Session.SessionID) ;
// Supprimer le cookie
SupprimerCookieRappel() ;
// Vider la session
HttpContext.Current.Session.Clear() ;
HttpContext.Current.Session.Abandon() ;
// Enregistrer la session en base de données
Private static void EnregistrerSessionEnBDD(int utilisateurId)
Try
Using (SqlConnection connection = new
SqlConnection(connectionString))
// D’abord, désactiver les anciennes sessions de cet utilisateur
String updateQuery = « UPDATE SessionsActives SET
EstActive = 0 WHERE UtilisateurId = @UtilisateurId » ;
Using (SqlCommand updateCmd = new
SqlCommand(updateQuery, connection))
{
updateCmd.Parameters.AddWithValue(« @UtilisateurId »,
utilisateurId) ;
connection.Open() ;
updateCmd.ExecuteNonQuery() ;
// Insérer la nouvelle session
String insertQuery = @ »INSERT INTO SessionsActives
(SessionId, UtilisateurId, DateExpiration,
AdresseIP, UserAgent)
VALUES (@SessionId, @UtilisateurId,
@DateExpiration, @AdresseIP, @UserAgent) » ;
Using (SqlCommand insertCmd = new
SqlCommand(insertQuery, connection))
insertCmd.Parameters.AddWithValue(« @SessionId »,
HttpContext.Current.Session.SessionID) ;
insertCmd.Parameters.AddWithValue(« @UtilisateurId »,
utilisateurId) ;
insertCmd.Parameters.AddWithValue(« @DateExpiration »,
DateTime.Now.AddMinutes(SESSION_TIMEOUT_MINUTES)) ;
insertCmd.Parameters.AddWithValue(« @AdresseIP »,
HttpContext.Current.Request.UserHostAddress) ;
insertCmd.Parameters.AddWithValue(« @UserAgent »,
HttpContext.Current.Request.UserAgent ?? « « ) ;
insertCmd.ExecuteNonQuery() ;
Catch (Exception)
{
// Log l’erreur
// Supprimer la session de la BDD
Private static void SupprimerSessionBDD(string sessionId)
Try
Using (SqlConnection connection = new
SqlConnection(connectionString))
String query = « UPDATE SessionsActives SET EstActive = 0
WHERE SessionId = @SessionId » ;
Using (SqlCommand command = new SqlCommand(query,
connection))
Command.Parameters.AddWithValue(« @SessionId »,
sessionId) ;
Connection.Open() ;
Command.ExecuteNonQuery() ;
Catch (Exception)
// Log l’erreur
}
}
// Créer un cookie de rappel
Private static void CreerCookieRappel(int utilisateurId)
String cookieValue = $ »{utilisateurId}_{DateTime.Now.Ticks} » ;
HttpCookie cookie = new HttpCookie(COOKIE_REMEMBER_KEY,
cookieValue)
Expires = DateTime.Now.AddDays(30), // Cookie valide 30 jours
HttpOnly = true,
Secure = HttpContext.Current.Request.IsSecureConnection
};
HttpContext.Current.Response.Cookies.Add(cookie) ;
// Vérifier le cookie de rappel
Private static Utilisateur VerifierCookieRappel()
HttpCookie cookie =
HttpContext.Current.Request.Cookies[COOKIE_REMEMBER_KEY] ;
If (cookie != null && !string.IsNullOrEmpty(cookie.Value))
Try
String[] parts = cookie.Value.Split(‘_’) ;
If (parts.Length == 2)
{
Int utilisateurId = int.Parse(parts[0]) ;
// Recharger l’utilisateur depuis la base
Var dal = new DAL.UtilisateurDAL() ;
Var utilisateur = dal.ObtenirUtilisateurParId(utilisateurId) ;
If (utilisateur != null && utilisateur.EstActif)
// Recréer la session
HttpContext.Current.Session[SESSION_USER_KEY] =
utilisateur ;
Return utilisateur ;
Catch (Exception)
// Cookie corrompu, le supprimer
SupprimerCookieRappel() ;
Return null ;
// Supprimer le cookie de rappel
Private static void SupprimerCookieRappel()
HttpCookie cookie = new HttpCookie(COOKIE_REMEMBER_KEY)
{
Expires = DateTime.Now.AddDays(-1),
Value = « «
};
HttpContext.Current.Response.Cookies.Add(cookie) ;
```
## Étape 5 : Classe de base pour les pages sécurisées
### Créer Utils/BasePage.cs
```csharp
Using System ;
Using System.Web.UI ;
Using GestionEtudiants.Utils ;
Namespace GestionEtudiants.Utils
Public class BasePage : Page
Protected override void OnLoad(EventArgs e)
// Vérifier si l’utilisateur est connecté
If ( !SessionManager.EstConnecte())
{
Response.Redirect(« ~/Login.aspx ?returnUrl= » +
Server.UrlEncode(Request.Url.PathAndQuery)) ;
Return ;
Base.OnLoad€ ;
Public class AdminBasePage : BasePage
Protected override void OnLoad(EventArgs e)
Base.OnLoad€ ;
// Vérifier si l’utilisateur est administrateur
If ( !SessionManager.EstAdministrateur())
Response.Redirect(« ~/AccesDenie.aspx ») ;
```
## Étape 6 : Pages de connexion et gestion des utilisateurs
### Créer Login.aspx
```aspx
<%@ Page Title= »Connexion » Language= »C# »
MasterPageFile= »~/Site.Master » AutoEventWireup= »true »
CodeBehind= »Login.aspx.cs » Inherits= »GestionEtudiants.Login » %>
<asp :Content ID= »Content1 » ContentPlaceHolderID= »MainContent »
runat= »server »>
<div class= »row »>
<div class= »col-md-4 col-md-offset-4 »>
<div class= »panel panel-default »>
<div class= »panel-heading »>
<h3 class= »panel-title »>
<span class= »glyphicon glyphicon-lock »></span>
Connexion
</h3>
</div>
<div class= »panel-body »>
<div class= »form-horizontal »>
<asp :ValidationSummary ID= »ValidationSummary1 »
runat= »server » CssClass= »text-danger » />
<div class= »form-group »>
<asp :Label runat= »server »
AssociatedControlID= »txtNomUtilisateur » CssClass= »col-md-12 »>Nom
d’utilisateur</asp :Label>
<div class= »col-md-12 »>
<div class= »input-group »>
<span class= »input-group-addon »><i
class= »glyphicon glyphicon-user »></i></span>
<asp :TextBox runat= »server »
ID= »txtNomUtilisateur » CssClass= »form-control » placeholder= »Nom
d’utilisateur » />
</div>
<asp :RequiredFieldValidator runat= »server »
ControlToValidate= »txtNomUtilisateur »
CssClass= »text-danger » ErrorMessage= »Le nom
d’utilisateur est requis. » Display= »Dynamic » />
</div>
</div>
<div class= »form-group »>
<asp :Label runat= »server »
AssociatedControlID= »txtMotDePasse » CssClass= »col-md-12 »>Mot de
passe</asp :Label>
<div class= »col-md-12 »>
<div class= »input-group »>
<span class= »input-group-addon »><i
class= »glyphicon glyphicon-lock »></i></span>
<asp :TextBox runat= »server »
ID= »txtMotDePasse » TextMode= »Password » CssClass= »form-control »
placeholder= »Mot de passe » />
</div>
<asp :RequiredFieldValidator runat= »server »
ControlToValidate= »txtMotDePasse »
CssClass= »text-danger » ErrorMessage= »Le mot
de passe est requis. » Display= »Dynamic » />
</div>
</div>
<div class= »form-group »>
<div class= »col-md-12 »>
<div class= »checkbox »>
<label>
<asp :CheckBox ID= »chkSeRappeler »
runat= »server » /> Se rappeler de moi
</label>
</div>
</div>
</div>
<div class= »form-group »>
<div class= »col-md-12 »>
<asp :Button runat= »server » ID= »btnConnecter »
Text= »Se connecter »
CssClass= »btn btn-primary btn-block »
OnClick= »btnConnecter_Click » />
</div>
</div>
<asp :Label ID= »lblMessage » runat= »server »
CssClass= »alert alert-danger » Visible= »false » style= »display : block ;
margin-top : 10px ; »></asp :Label>
</div>
</div>
</div>
<div class= »panel panel-info »>
<div class= »panel-heading »>
<h4 class= »panel-title »>Comptes de test</h4>
</div>
<div class= »panel-body »>
<p><strong>Administrateur :</strong> admin /
admin123</p>
<p><strong>Gestionnaire :</strong> gestionnaire /
user123</p>
</div>
</div>
</div>
</div>
</asp :Content>
```
### Code-
Je vais terminer ce projet de système de gestion des utilisateurs avec
sessions et cookies. Voici la suite du code manquant :
using System;
using System.Web.UI;
using GestionEtudiants.DAL;
using GestionEtudiants.Utils;
namespace GestionEtudiants
public partial class Login : Page
protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
// Si l'utilisateur est déjà connecté, le rediriger
if (SessionManager.EstConnecte())
{
RedirigerUtilisateur();
protected void btnConnecter_Click(object sender, EventArgs e)
if (Page.IsValid)
string nomUtilisateur = txtNomUtilisateur.Text.Trim();
string motDePasse = txtMotDePasse.Text;
bool seRappeler = chkSeRappeler.Checked;
UtilisateurDAL dal = new UtilisateurDAL();
var utilisateur = dal.Authentifier(nomUtilisateur, motDePasse);
if (utilisateur != null)
// Mettre à jour la dernière connexion
dal.MettreAJourDerniereConnexion(utilisateur.Id);
// Créer la session
SessionManager.CreerSession(utilisateur, seRappeler);
// Rediriger l'utilisateur
RedirigerUtilisateur();
else
{
lblMessage.Text = "Nom d'utilisateur ou mot de passe
incorrect.";
lblMessage.Visible = true;
private void RedirigerUtilisateur()
string returnUrl = Request.QueryString["returnUrl"];
if (!string.IsNullOrEmpty(returnUrl))
Response.Redirect(returnUrl);
else
Response.Redirect("~/Default.aspx");
using System;
using System.Web.UI;
using GestionEtudiants.Utils;
namespace GestionEtudiants
{
public partial class Logout : Page
protected void Page_Load(object sender, EventArgs e)
// Déconnecter l'utilisateur
SessionManager.Deconnecter();
// Rediriger vers la page de connexion
Response.Redirect("~/Login.aspx");
<%@ Page Title="Gestion des Utilisateurs" Language="C#"
MasterPageFile="~/Site.Master" AutoEventWireup="true"
CodeBehind="GestionUtilisateurs.aspx.cs"
Inherits="GestionEtudiants.GestionUtilisateurs" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
runat="server">
<div class="row">
<div class="col-md-12">
<h2>
<span class="glyphicon glyphicon-user"></span> Gestion des
Utilisateurs
<asp:Button ID="btnNouvelUtilisateur" runat="server"
Text="Nouvel Utilisateur"
CssClass="btn btn-primary pull-right"
OnClick="btnNouvelUtilisateur_Click" />
</h2>
<hr />
</div>
</div>
<!-- Message de succès ou d'erreur -->
<asp:Panel ID="pnlMessage" runat="server" Visible="false">
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert">
<span>×</span>
</button>
<asp:Label ID="lblMessage" runat="server"></asp:Label>
</div>
</asp:Panel>
<!-- Formulaire de création/modification d'utilisateur -->
<asp:Panel ID="pnlFormulaireUtilisateur" runat="server" Visible="false"
CssClass="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<asp:Label ID="lblTitreFormulaire" runat="server" Text="Nouvel
Utilisateur"></asp:Label>
<button type="button" class="close" onclick="$('#<%=
pnlFormulaireUtilisateur.ClientID %>').hide();">
<span>×</span>
</button>
</h4>
</div>
<div class="panel-body">
<div class="form-horizontal">
<asp:ValidationSummary ID="ValidationSummary1"
runat="server" CssClass="alert alert-danger" />
<asp:HiddenField ID="hfUtilisateurId" runat="server" />
<div class="form-group">
<asp:Label runat="server"
AssociatedControlID="txtNomUtilisateur" CssClass="col-md-2 control-
label">Nom d'utilisateur</asp:Label>
<div class="col-md-4">
<asp:TextBox runat="server" ID="txtNomUtilisateur"
CssClass="form-control" />
<asp:RequiredFieldValidator runat="server"
ControlToValidate="txtNomUtilisateur"
CssClass="text-danger" ErrorMessage="Le nom
d'utilisateur est requis." Display="Dynamic" />
</div>
<asp:Label runat="server" AssociatedControlID="txtEmail"
CssClass="col-md-2 control-label">Email</asp:Label>
<div class="col-md-4">
<asp:TextBox runat="server" ID="txtEmail"
CssClass="form-control" TextMode="Email" />
<asp:RequiredFieldValidator runat="server"
ControlToValidate="txtEmail"
CssClass="text-danger" ErrorMessage="L'email est
requis." Display="Dynamic" />
<asp:RegularExpressionValidator runat="server"
ControlToValidate="txtEmail"
CssClass="text-danger" ErrorMessage="Format d'email
invalide." Display="Dynamic"
ValidationExpression="^[\w\.-]+@[\w\.-]+\.\w+$" />
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="txtNom"
CssClass="col-md-2 control-label">Nom</asp:Label>
<div class="col-md-4">
<asp:TextBox runat="server" ID="txtNom"
CssClass="form-control" />
<asp:RequiredFieldValidator runat="server"
ControlToValidate="txtNom"
CssClass="text-danger" ErrorMessage="Le nom est
requis." Display="Dynamic" />
</div>
<asp:Label runat="server" AssociatedControlID="txtPrenom"
CssClass="col-md-2 control-label">Prénom</asp:Label>
<div class="col-md-4">
<asp:TextBox runat="server" ID="txtPrenom"
CssClass="form-control" />
<asp:RequiredFieldValidator runat="server"
ControlToValidate="txtPrenom"
CssClass="text-danger" ErrorMessage="Le prénom est
requis." Display="Dynamic" />
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="ddlProfil"
CssClass="col-md-2 control-label">Profil</asp:Label>
<div class="col-md-4">
<asp:DropDownList ID="ddlProfil" runat="server"
CssClass="form-control"
DataTextField="NomProfil" DataValueField="Id">
</asp:DropDownList>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="ddlProfil" InitialValue=""
CssClass="text-danger" ErrorMessage="Le profil est
requis." Display="Dynamic" />
</div>
<asp:Label runat="server"
AssociatedControlID="txtMotDePasse" CssClass="col-md-2 control-
label">Mot de passe</asp:Label>
<div class="col-md-4">
<asp:TextBox runat="server" ID="txtMotDePasse"
CssClass="form-control" TextMode="Password" />
<asp:RequiredFieldValidator runat="server"
ID="rfvMotDePasse" ControlToValidate="txtMotDePasse"
CssClass="text-danger" ErrorMessage="Le mot de passe
est requis." Display="Dynamic" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-4">
<div class="checkbox">
<label>
<asp:CheckBox ID="chkEstActif" runat="server"
Checked="true" /> Utilisateur actif
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<asp:Button runat="server" ID="btnEnregistrer"
Text="Enregistrer"
CssClass="btn btn-success"
OnClick="btnEnregistrer_Click" />
<asp:Button runat="server" ID="btnAnnuler"
Text="Annuler" CausesValidation="false"
CssClass="btn btn-default"
OnClick="btnAnnuler_Click" />
</div>
</div>
</div>
</div>
</asp:Panel>
<!-- Liste des utilisateurs -->
<div class="row">
<div class="col-md-12">
<div class="table-responsive">
<asp:GridView ID="gvUtilisateurs" runat="server"
CssClass="table table-striped table-hover"
AutoGenerateColumns="false" DataKeyNames="Id"
OnRowCommand="gvUtilisateurs_RowCommand"
EmptyDataText="Aucun utilisateur trouvé.">
<Columns>
<asp:BoundField DataField="NomUtilisateur"
HeaderText="Nom d'utilisateur" />
<asp:BoundField DataField="NomComplet"
HeaderText="Nom complet" />
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:BoundField DataField="Profil.NomProfil"
HeaderText="Profil" />
<asp:TemplateField HeaderText="Statut">
<ItemTemplate>
<span class="label <%# (bool)Eval("EstActif") ?
"label-success" : "label-danger" %>">
<%# (bool)Eval("EstActif") ? "Actif" : "Inactif" %>
</span>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DateCreation"
HeaderText="Date création" DataFormatString="{0:dd/MM/yyyy}" />
<asp:BoundField DataField="DerniereConnexion"
HeaderText="Dernière connexion"
DataFormatString="{0:dd/MM/yyyy HH:mm}"
NullDisplayText="Jamais" />
<asp:TemplateField HeaderText="Actions" ItemStyle-
Width="150px">
<ItemTemplate>
<asp:LinkButton ID="btnModifier" runat="server"
CommandName="Modifier"
CommandArgument='<%# Eval("Id") %>'
CssClass="btn btn-sm btn-warning">
<span class="glyphicon glyphicon-edit"></span>
Modifier
</asp:LinkButton>
<asp:LinkButton ID="btnSupprimer" runat="server"
CommandName="Supprimer"
CommandArgument='<%# Eval("Id") %>'
CssClass="btn btn-sm btn-danger"
OnClientClick="return confirm('Êtes-vous sûr de
vouloir supprimer cet utilisateur ?');">
<span class="glyphicon glyphicon-trash"></span>
Supprimer
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
</div>
</asp:Content>
using System;
using System.Linq;
using System.Web.UI.WebControls;
using GestionEtudiants.DAL;
using GestionEtudiants.Models;
using GestionEtudiants.Utils;
namespace GestionEtudiants
public partial class GestionUtilisateurs : AdminBasePage
private UtilisateurDAL utilisateurDAL = new UtilisateurDAL();
protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
{
ChargerProfils();
ChargerUtilisateurs();
private void ChargerProfils()
var profils = utilisateurDAL.ObtenirTousLesProfils();
ddlProfil.DataSource = profils;
ddlProfil.DataBind();
ddlProfil.Items.Insert(0, new ListItem("-- Sélectionner un profil --",
""));
private void ChargerUtilisateurs()
var utilisateurs = utilisateurDAL.ObtenirTousLesUtilisateurs();
gvUtilisateurs.DataSource = utilisateurs;
gvUtilisateurs.DataBind();
protected void btnNouvelUtilisateur_Click(object sender, EventArgs e)
ViderFormulaire();
lblTitreFormulaire.Text = "Nouvel Utilisateur";
rfvMotDePasse.Enabled = true;
pnlFormulaireUtilisateur.Visible = true;
pnlMessage.Visible = false;
}
protected void btnEnregistrer_Click(object sender, EventArgs e)
if (Page.IsValid)
try
var utilisateur = new Utilisateur
NomUtilisateur = txtNomUtilisateur.Text.Trim(),
Email = txtEmail.Text.Trim(),
Nom = txtNom.Text.Trim(),
Prenom = txtPrenom.Text.Trim(),
ProfilId = int.Parse(ddlProfil.SelectedValue),
EstActif = chkEstActif.Checked
};
bool succes = false;
string message = "";
if (string.IsNullOrEmpty(hfUtilisateurId.Value)) // Nouveau
// Vérifier si le nom d'utilisateur existe déjà
var utilisateurs =
utilisateurDAL.ObtenirTousLesUtilisateurs();
if (utilisateurs.Any(u =>
u.NomUtilisateur.Equals(txtNomUtilisateur.Text.Trim(),
StringComparison.OrdinalIgnoreCase)))
{
AfficherMessage("Ce nom d'utilisateur existe déjà.",
false);
return;
// Vérifier si l'email existe déjà
if (utilisateurs.Any(u =>
u.Email.Equals(txtEmail.Text.Trim(),
StringComparison.OrdinalIgnoreCase)))
AfficherMessage("Cette adresse email existe déjà.",
false);
return;
succes = utilisateurDAL.CreerUtilisateur(utilisateur,
txtMotDePasse.Text);
message = succes ? "Utilisateur créé avec succès." :
"Erreur lors de la création de l'utilisateur.";
else // Modification
utilisateur.Id = int.Parse(hfUtilisateurId.Value);
succes = utilisateurDAL.ModifierUtilisateur(utilisateur,
string.IsNullOrEmpty(txtMotDePasse.Text) ? null :
txtMotDePasse.Text);
message = succes ? "Utilisateur modifié avec succès." :
"Erreur lors de la modification de l'utilisateur.";
AfficherMessage(message, succes);
if (succes)
pnlFormulaireUtilisateur.Visible = false;
ChargerUtilisateurs();
catch (Exception ex)
AfficherMessage("Une erreur est survenue: " + ex.Message,
false);
protected void btnAnnuler_Click(object sender, EventArgs e)
pnlFormulaireUtilisateur.Visible = false;
pnlMessage.Visible = false;
ViderFormulaire();
protected void gvUtilisateurs_RowCommand(object sender,
GridViewCommandEventArgs e)
int utilisateurId = Convert.ToInt32(e.CommandArgument);
switch (e.CommandName)
case "Modifier":
ChargerUtilisateurPourModification(utilisateurId);
break;
case "Supprimer":
SupprimerUtilisateur(utilisateurId);
break;
private void ChargerUtilisateurPourModification(int utilisateurId)
var utilisateur =
utilisateurDAL.ObtenirUtilisateurParId(utilisateurId);
if (utilisateur != null)
hfUtilisateurId.Value = utilisateur.Id.ToString();
txtNomUtilisateur.Text = utilisateur.NomUtilisateur;
txtEmail.Text = utilisateur.Email;
txtNom.Text = utilisateur.Nom;
txtPrenom.Text = utilisateur.Prenom;
ddlProfil.SelectedValue = utilisateur.ProfilId.ToString();
chkEstActif.Checked = utilisateur.EstActif;
txtMotDePasse.Text = "";
lblTitreFormulaire.Text = "Modifier l'Utilisateur";
rfvMotDePasse.Enabled = false; // Mot de passe optionnel en
modification
pnlFormulaireUtilisateur.Visible = true;
pnlMessage.Visible = false;
}
private void SupprimerUtilisateur(int utilisateurId)
// Ne pas permettre la suppression de son propre compte
var utilisateurConnecte =
SessionManager.ObtenirUtilisateurConnecte();
if (utilisateurConnecte.Id == utilisateurId)
AfficherMessage("Vous ne pouvez pas supprimer votre propre
compte.", false);
return;
bool succes = utilisateurDAL.SupprimerUtilisateur(utilisateurId);
string message = succes ? "Utilisateur supprimé avec succès." :
"Erreur lors de la suppression de l'utilisateur.";
AfficherMessage(message, succes);
if (succes)
ChargerUtilisateurs();
private void ViderFormulaire()
hfUtilisateurId.Value = "";
txtNomUtilisateur.Text = "";
txtEmail.Text = "";
txtNom.Text = "";
txtPrenom.Text = "";
ddlProfil.SelectedIndex = 0;
chkEstActif.Checked = true;
txtMotDePasse.Text = "";
private void AfficherMessage(string message, bool succes)
lblMessage.Text = message;
pnlMessage.CssClass = succes ? "alert alert-success alert-
dismissible" : "alert alert-danger alert-dismissible";
pnlMessage.Visible = true;
// Ajouter ces méthodes à la classe UtilisateurDAL existante
// Modifier un utilisateur
public bool ModifierUtilisateur(Utilisateur utilisateur, string
nouveauMotDePasse = null)
try
using (SqlConnection connection = new
SqlConnection(connectionString))
string query;
if (!string.IsNullOrEmpty(nouveauMotDePasse))
{
query = @"UPDATE Utilisateurs SET
NomUtilisateur = @NomUtilisateur,
Email = @Email,
MotDePasse = @MotDePasse,
Nom = @Nom,
Prenom = @Prenom,
ProfilId = @ProfilId,
EstActif = @EstActif
WHERE Id = @Id";
else
query = @"UPDATE Utilisateurs SET
NomUtilisateur = @NomUtilisateur,
Email = @Email,
Nom = @Nom,
Prenom = @Prenom,
ProfilId = @ProfilId,
EstActif = @EstActif
WHERE Id = @Id";
using (SqlCommand command = new SqlCommand(query,
connection))
command.Parameters.AddWithValue("@Id", utilisateur.Id);
command.Parameters.AddWithValue("@NomUtilisateur",
utilisateur.NomUtilisateur);
command.Parameters.AddWithValue("@Email",
utilisateur.Email);
command.Parameters.AddWithValue("@Nom", utilisateur.Nom);
command.Parameters.AddWithValue("@Prenom",
utilisateur.Prenom);
command.Parameters.AddWithValue("@ProfilId",
utilisateur.ProfilId);
command.Parameters.AddWithValue("@EstActif",
utilisateur.EstActif);
if (!string.IsNullOrEmpty(nouveauMotDePasse))
command.Parameters.AddWithValue("@MotDePasse",
HashMotDePasse(nouveauMotDePasse));
connection.Open();
int result = command.ExecuteNonQuery();
return result > 0;
catch (Exception)
return false;
// Supprimer un utilisateur (soft delete)
public bool SupprimerUtilisateur(int id)
try
{
using (SqlConnection connection = new
SqlConnection(connectionString))
string query = "UPDATE Utilisateurs SET EstActif = 0 WHERE Id =
@Id";
using (SqlCommand command = new SqlCommand(query,
connection))
command.Parameters.AddWithValue("@Id", id);
connection.Open();
int result = command.ExecuteNonQuery();
return result > 0;
catch (Exception)
return false;
// Vérifier si un nom d'utilisateur existe
public bool NomUtilisateurExiste(string nomUtilisateur, int? excludeId =
null)
try
{
using (SqlConnection connection = new
SqlConnection(connectionString))
string query = "SELECT COUNT(*) FROM Utilisateurs WHERE
NomUtilisateur = @NomUtilisateur";
if (excludeId.HasValue)
query += " AND Id != @ExcludeId";
using (SqlCommand command = new SqlCommand(query,
connection))
command.Parameters.AddWithValue("@NomUtilisateur",
nomUtilisateur);
if (excludeId.HasValue)
command.Parameters.AddWithValue("@ExcludeId",
excludeId.Value);
connection.Open();
int count = (int)command.ExecuteScalar();
return count > 0;
catch (Exception)
return false;
}
}
// Vérifier si un email existe
public bool EmailExiste(string email, int? excludeId = null)
try
using (SqlConnection connection = new
SqlConnection(connectionString))
string query = "SELECT COUNT(*) FROM Utilisateurs WHERE Email
= @Email";
if (excludeId.HasValue)
query += " AND Id != @ExcludeId";
using (SqlCommand command = new SqlCommand(query,
connection))
command.Parameters.AddWithValue("@Email", email);
if (excludeId.HasValue)
command.Parameters.AddWithValue("@ExcludeId",
excludeId.Value);
connection.Open();
int count = (int)command.ExecuteScalar();
return count > 0;
}
catch (Exception)
return false;
<!-- Ajouter ce code dans la navbar de Site.Master après les liens existants
-->
<!-- Menu utilisateur connecté -->
<% if (GestionEtudiants.Utils.SessionManager.EstConnecte()) { %>
<ul class="nav navbar-nav">
<li><a href="Default.aspx">Accueil</a></li>
<li><a href="GestionEtudiants.aspx">Étudiants</a></li>
<!-- Menu admin -->
<% if (GestionEtudiants.Utils.SessionManager.EstAdministrateur())
{ %>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"
role="button">
Administration <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="GestionUtilisateurs.aspx">Gestion des
Utilisateurs</a></li>
<li><a href="SessionsActives.aspx">Sessions
Actives</a></li>
</ul>
</li>
<% } %>
</ul>
<!-- Utilisateur connecté -->
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"
role="button">
<span class="glyphicon glyphicon-user"></span>
<%=
GestionEtudiants.Utils.SessionManager.ObtenirUtilisateurConnecte().NomC
omplet %>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li class="dropdown-header">
Profil: <%=
GestionEtudiants.Utils.SessionManager.ObtenirUtilisateurConnecte().Profil.
NomProfil %>
</li>
<li role="separator" class="divider"></li>
<li><a href="MonProfil.aspx">Mon Profil</a></li>
<li><a href="ChangerMotDePasse.aspx">Changer le mot de
passe</a></li>
<li role="separator" class="divider"></li>
<li><a href="Logout.aspx">Se déconnecter</a></li>