16-4 Authentification
L'action Authentifier
fait peu de choses pour le moment. Remédions à la situation!
Injection de SignInManager
Créez un constructeur pour le contrôleur qui injecte le SignInManager
de Identity
.
[Route("[controller]")] // Préfixe d'URL /auth
public class AuthController : Controller
{
private readonly SignInManager<ApplicationUser> _signInManager;
public AuthController(SignInManager<ApplicationUser> signInManager)
{
_signInManager = signInManager;
}
//...
Le SignInManager
fait partie de Identity
et pourra être utilisé afin de vérifier si la combinaison de courriel / mot de passe est bonne pour ensuite créer une session.
Le SignInManager
utilisera le UserRepository
pour effectuer les requêtes dont il a besoin pour authentifier l'utilisateur.
Authentification via SignInManager
Tenter l'authentification si un courriel et un mot de passe ont été reçus
Si nous avons reçu un courriel et un mot de passe, nous pourrons procéder à l'authentification. Pour procéder à l'authentification, SignInManager
possède une fonction PasswordSignInAsync
qui prend en argument un courriel, un mot de passe et deux autres paramètres supplémentaires auxquels nous reviendrons.
public async Task<IActionResult> Authentifier(ConnexionViewModel connexionViewModel)
{
if (connexionViewModel.Email != null &&
connexionViewModel.Password != null)
{
var result = await _signInManager.PasswordSignInAsync(
connexionViewModel.Email,
connexionViewModel.Password,
true,
lockoutOnFailure: false
);
}
return Ok();
}
PasswordSignInAsync
: fonction utilisée sur le SignInManager
pour authentifier l'utilisateur.
viewModel.Email
: courriel de l'utilisateur pour l'authentification
viewModel.Password
: mot de passe de l'utilisateur
true
(isPersistent
): on veut que la session reste active même si l'onglet ou le navigateur est fermé
lockoutOnFailure: false
: on ne veut pas barrer le compte lors d'un échec
PasswordSignInAsync
utilise votre UserRepository
! Particulièrement les fonctions FindByNameAsync
qui permet de récupérer un utilisateur par son courriel et ensuite GetPasswordHashAsync
qui permet d'obtenir le hash de l'utilisateur.
La fonction effectue ensuite une comparaison entre le hash en bd et la version hashée à partir du mot de passe reçu.
Gestion du résultat
On doit gérer le retour de PasswordSignInAsync
:
- Si OK, on redirige vers l'accueil, l'utilisateur est authentifié
- S'il y a une erreur, probablement que la combinaison courriel/mot de passe n'est pas la bonne, on doit afficher un message d'erreur.
- Afficher le message d'erreur implique de retourner la vue
-
Gérer les deux situations énoncées précédemment.
Snowfall.Web.Mvc/Controllers/AuthController.cspublic async Task<IActionResult> Authentifier(ConnexionViewModel connexionViewModel)
{
if (connexionViewModel.Email != null &&
connexionViewModel.Password != null)
{
var result = await _signInManager.PasswordSignInAsync(
connexionViewModel.Email,
connexionViewModel.Password,
true,
lockoutOnFailure: false
);
if (result.Succeeded)
return RedirectToAction("Index", "Evenements");
ModelState.AddModelError("Authentification.Echec", "La combinaison de courriel et mot de passe est invalide ou il est impossible de vous authentifier.");
return View("Connexion", connexionViewModel);
}
return Ok();
}infoIl est possible de pousser des erreurs personnalisées dans le
ModelState
. Ici on assigne à une cl éAuthentification.Echec
un message d'erreur qui sera récupéré dans la vue. Nous verrons sous peu comment l'afficher. -
Gérer le retour dans le cas où les informations de connexion ne sont pas fournies (vides). On veut dans ce cas simplement retourner la vue de connexion pour permettre à l'utilisateur d'entrer les informations.
Snowfall.Web.Mvc/Controllers/AuthController.cspublic async Task<IActionResult> Authentifier(ConnexionViewModel connexionViewModel)
{
if (connexionViewModel.Email != null &&
connexionViewModel.Password != null)
{
var result = await _signInManager.PasswordSignInAsync(
connexionViewModel.Email,
connexionViewModel.Password,
true,
lockoutOnFailure: false
);
if (result.Succeeded)
return RedirectToAction("Index", "Evenements");
ModelState.AddModelError("Authentification.Echec", "La combinaison de courriel et mot de passe est invalide ou il est impossible de vous authentifier.");
return View("Connexion", connexionViewModel);
}
return View("Connexion", connexionViewModel);
}
Afficher le message d'erreur dans la vue
Pour afficher le message d'erreur dans la vue, on peut utiliser ceci, dans le haut du formulaire:
<!-- ... -->
<h1 class="mb-3">Connexion</h1>
@if (Html.ViewData.ModelState["Authentification.Echec"]?.Errors.Count > 0)
{
<div class="alert alert-danger">
@Html.ValidationMessage("Authentification.Echec")
</div>
}
<!-- ... -->
Test variés de la connexion
Vous pouvez essayer le formulaire de connexion. Utilisez le courriel et mot de passe que vous avez utilisé dans vos seeds.
- Sans accès valides, pour vérifier que le message d'erreur est affiché
- Avec un accès valide, pour vérifier que nous sommes bien redirigés vers l'accueil