Treballar amb autenticació d'usuaris en ASP.NET MVC 5 - Gestió, creació, validació de passwords i bloqueig d'usuaris

Si en el moment de crear un projecte ASP.NET MVC a Visual Studio esculls l'opció d'autenticació d'usuaris "Cuentas de usuario inidviduales" o "Individual User Account" en anglès, es crearà automàtiament tot un sistema de gestió d'usuaris a través de funcions com: Registre d'usuari, Login d'usuari, canvi en la informació de l'ususari etc..

Tot i així, és important conèixer com treballar amb els usuaris i personalitzar-ne la gestió per tal que puguem donar solució als requeriments que se'ns poden plantejar.

Per començar creem un projecte nou i en una de les pantalles li diem que volem treballar amb autenticació d'usuaris. Per això quan veiem el botó "cambiar autenticación" el premem i selecconem l'opció hem de prémer el botó "Cuentas de usuario inidviduales" o "Individual User Account" en anglès.



Una de les primeres coses que ens interessar saber d'un usuari és si està autenticat. Per als exemples que treballarem aquí, ho farem des del HomeControler.cs > ActionResult Index() . 

Ara veurem que és el UserManager i com utilitzar-lo. Anem a HomeControler.cs > ActionResult Index(), un cop aquí escribim el següent codi:

using WebApplication9.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication9.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var estaAutenticat = User.Identity.IsAuthenticated;
if (estaAutenticat)
{
var nomUsuari = User.Identity.Name;
var id = User.Identity.GetUserId();
//Necessitem using Microsoft.AspNet.Identity;

//Instanciem l'ApplicationDbContext
using (ApplicationDbContext db = new ApplicationDbContext())
{


//Podem fer querys amb EntityFramework a la taula AspNetUsers, obtenir valors i desar-los en una variable i d'altres accions
var usuari = db.Users.Where(x => x.Id == id).FirstOrDefault();
var mailConfirmat = usuari.EmailConfirmed;

//Instanciem el UserManager i li passem com a argument l'ApplicationDbContext per mitjà de la variable db

var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));

//En una variable, a la qual l'anomenem "user ", guardem els valors de l'usuari per posteriorment utilitzar-los en la seva creació. Abans instanciem l'ApplicationUser
var user = new ApplicationUser();
user.UserName="Josep Vendrell";
user.Email="josepv@gmail.com";

//Crear l'usuari
var resultat = userManager.Create(user,"PasswordJosep@123");
}
}
return View();
}
}
}



El primer que veiem és la variable estaAutenticat que fa referència al valor IsAuthenticated. Des del controlador se'ns ofereix la possibilitat d'obtenir la informació de l'usuari, al menys allò més essencial  anant a la variable User.Identity.    i llavors ens ofereix una serie d'informació. Per exemple, ens ofereix la possibilitat d'obtenir l'id de l'usuari actual.


Abans d'obtenir l'id de l'usuari actual seria bo saber si l'usuari està autenticat. Per això el que fem primer és utilitzar la propietat IsAuthenticated. Si posem un punt d'interrupció a la línea 
var estaAutenticat = User.Identity.IsAuthenticated i executem el projecte en mode depuració ( prement F5 o a través del menú Depurar > Iniciar depuración  ), com que l'hem creat de nou, encara no hem registrat cap usuari i per això veurem com el valor de la variable IsAuthenticated és false.



Així doncs, el primer que farem serà registrar un usuari a través de la pàgina web que proporciona el projecte per defecte.




Quan premem el botó "Registrarse" el primer que farà el sistema és buscar si hi ha una base de dades creada per nosaltres. Si no existeix la crearà utilitzant el motor intern del sistema: LocalDB. En el nostre cas utilitzarem una base de dades anomenada bdproves que hem creat a SQL Server. Per inidcar que la utilitzi i hi registri els usuaris, posarem el següent connectionString al Web.config.

<connectionStrings>
    <add name="bdProvesConnections" connectionString="data source=CESC-PC\SQLEXPRESS;initial catalog=bdProves;persist security info=True;user id=sa;password=mypassword123;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings> 

És molt important que el nom de la connexió coincideixi en els Web.config i en la classe ApplicationDbContext que es troba dins de la carpeta Models i el fitxer IdentityModels.cs.






Un cop registrats veiem com apareix el nom a la part superior del projecte


Com que li hem dit al Web.config i ApplicationDbContext que la base de dades amb la que treballem es diu bdProves i es troba a SQL Server, si hi anem veurem que s'han creat les taules que gestionen l'autenticació d'usuaris: AspNetRoles, AspNetUserClaims, AspNetUserLogins, AspNetUserRoles, AspNetUsers. Si obrim la taula AspNetUser veurem que s'ha creat el nostre usuari.

Ara si tornem a executar el projecte en mode Depuració i mirem el valor de la variable IsAuthenticated veurem que ara és True.


Ara veiem que el valor de la variable estaAutenticat és True i per tant entrarem dins el bloc if. Dins aquest bloc veiem com identity ens permet obtenir informació de l'usuari, tal com el nom de l'usuari, el seu id, per mitjà de la funció var id = User.Identity.GetUserId(); Per utilitzar la funció .GetUserId()has de col·locar la directiva Using.Microsoft.AspNet.Identity en la part superior de la classe.

També podem obtenir tota la informació de l'usuari utilitzant EntityFramework ja que permet, via un dbSet en l'ApplicationDbContext la possibilitat de fer Querys a la taula d'usuaris ( AspNetUsers, creada a SQL Server ) com podem veure a continació:

 var usuari = db.Users.Where(x => x.Id == id).FirstOrDefault();
 var mailConfirmat = usuari.EmailConfirmed;

Disposem d'una classe que abstrau moltes de les funcions comuns que volem utilitzar per gestionar usuaris. Aquesta classe és la UserManager la qual ens ofereix una serie d'informacions respecte a la configuració que tenim en ASPNET.MVC en relació als usuaris.

Anem a veure ara com crear un usuari de manera manual. Per fer això utilitzarem el userManager amb el mètode create.

Crearem un usuari amb nom ( UserName ) Josep Vendrell, Email PasswordJosep@123 

using (ApplicationDbContext db = new ApplicationDbContext())
{                {
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));

var user = new ApplicationUser();
user.UserName="Josep Vendrell";
user.Email="josepv@gmail.com";

//Crear usuari
var resultat = userManager.Create(user,"PasswordJosep@123");
}

Fixem-nos que al crear l'usuari no li hem dit db.SaveChanges. No hem dit guardar canvis a l'ApllicationDbContext, i els canvis s'han guardat automàticament. Això és pequè quan hem instanciat el UserManager ( using (ApplicationDbContext db = new ApplicationDbContext()
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));) li passem com argument l'ApplicationDbContext. Això fa que ASPNET.MVC internament faci totes les operacions necessàries perquè allò que li demanem ho faci sense necessitat de guardar canvis.

UserManager ens ofereix moltes funcions, a més de la de crear usuaris.



Per exemple, amb UserManager podem obtenir l'Id de l'usuari de la taula ASPNetUsers que es troba a l'SQL Server de forma ràpida:

var id = User.Identity.GetUserId();
var usuari2 = userManager.FindById(id);

Regles de validació de password

La gestió d'usuaris en ASP.NET MVC és bastant restictiva en quan a les contrasenyes ja que per defecte obliga a que hi hagi una majúscula, un símbol, números i lletres. Si volem personalitzar i felxibilitzar la validació de contrasenyes hem d'anar a IdentityConfig.cs, que es troba a la carpeta App_Start > IdentityConfig.cs



Un cop dins d'IdentityConfig.cs anem baixant fins a trobar el lloc on es defineixen les regles de validació del password.




Gestionar el bloqueig d'usuaris ( Lockout )

Més avall de l'IdentityConfig.cs també podem veure les regles de validació del lockout, és a dir, el nombre d'intents fallits que pots tenir abans no et bloquegi l'aplicació.

En l'exemple següent l'aplicació ens bloquejarà l'accés durant 5 minuts després de 5 intents fallits d'inici de sessió.
Per a completar la gestió de bloqueijos, i perquè funcionin les regles de bolqueig establertes hem d'anar també a l'AccountController.cs fins a l'opció ShoudLockout.




Comentaris

Entrades populars