Nuevamente saludos mis nunca bien ponderados y siempre incomprendidos compañeros desarrolladores, continuo con la tercera parte de una serie de posts que comprenden la creación de usuarios con ASP.Net Identity y Login de usuarios con Owin.
Pues bien quiero que ahora acerquen sus caras a los monitores y vean acá:
Espero haber ajustado bien el Neuralizador y no hayan olvidado como encender la computadora, ya que justo necesito que olviden lo que leyeron en los dos posts previos. Estos posts anteriores eran necesarios para este nuevo post que van a leer, ya que Identity y Owin pueden ser complejos de entender en un principio y en esos primeros posts... Ehm bueno... digamos que no era la forma correcta de hacer las cosas (como pudieron darse cuenta).
En esta ocasión ya habiendo entendido la mecánica del manejo de seguridad en ASP.Net vayamos al manejo de roles directamente en un entorno MVC, con sus controllers, views y cualquier otra cosa rara que haya allí.
Lo primero es crear la solución Web .Net, especificamos el nombre del proyecto y la ruta de prefencia, hacemos click en aceptar y nos detendremos en la pantalla que sigue a continuación
Recuerdan que en los posts previos les decia que debían mantener la opción: "Authentication: No Authentication" ¡Pues si lo recuerdan está muy mal hecho porque esa es una de las cosas que deben olvidar! Primero debemos seleccionar en los templates el patrón MVC y automáticamente la opción "Authentication" cambiará a "Individual User Accounts", ambas cosas son fundamentales para nuestro proyecto con seguridad integrada.
¡Ah casi me olvidaba! El post original pueden leerlo ACÁ creado por Mahesh Sabnis.
La primera sorpresa que nos topamos es que no es necesario incluír los paquetes de Identity ni de Owin, ya que están incluidos con la creación del proyecto, de todas formas no está de más validar:
Noten además que hay nuevos elementos, en la carpeta de controllers un objeto llamado AccountController el cual está dedicado exclusivamente a la gestión de usuarios y roles y en las vistas una carpeta llamada Account dedicada a la parte visual de la gestión del controlador.
Otro elemento importante está en la carpeta Models, allí se encuentran las propiedades de los objetos que conforman la aplicación de las reglas de negocio para validación de passwords, existencia de usuarios con el mismo Username, etc.
Ahora comienza la diversión, ubiquemos dentro de la carpeta Models una clase llamada AccountViewModel.cs, como apreciarán hay una buena cantidad de clases dedicadas a la gestion de los usuarios (validaciones, manejos de passwords, etc) ubiquemos una clase llamada RegisterViewModel y añadamos una nueva propiedad llamada Name
public string Name { get; set; }
La clase debe verse de esta manera:
Algunos detalles acá: Las propiedades tienen algunos atributos, por ejemplo [Required] es para obligar al controlador y a la vista a pedir este campo de forma obligatoria o de lo contrario no habrá manera en que el registro sea almacenado; [EmailAddress] es un atributo interesante ya que implica que en la vista el campo que esté destinado como input del correo tenga el formato de un correo electrónico (yeah, no more validators controls); Por último hay un atributo llamado StringLength que limita el input a determinados caracteres de longitud, ojo no va a restringir la entrada en la caja de texto, simplemente si el valor enviado en este campo supera ese valor un mensaje de error será enviado a la vista.
Luego hacemos click derecho con el mouse sobre la carpeta Controllers Agregar -> Controller, seleccionamos un controlador vacío
Y especificamos como nombre RoleController
Click en aceptar y validamos que el archivo se haya creado y lo modificamos para que contenga el siguiente código:
Importante noten las referencias a:
using Microsoft.AspNet.Identity.EntityFramework;
y a:
using TestRolesMVC_2.Models;
La primera es el paquete de Identity con la cantidad de referencias necesarias para la administración de los usuarios, mientras que la segunda hace un llamado a las clases contenidas en la carpeta Models, en el using se instancia a TestRolesMVC_2 ya que así nombré a mi proyecto (se que muchos saben esto, pero creanme, se pueden presentar confusiones muchas veces si esto no se aclara, especialmente si se es amigo del Ctrl + V).
Un detalle para quienes dan los primeros pasos con MVC 5, los controllers y los views estan estrechamente vinculados, pueden apreciar que uno de los métodos (Create) posee un atributo [HttpPost] y otro no, la razón básica de esto es que uno llama al View (con un Get) y el otro simplemente recibe del View (con un Post), es algo parecido a una sobrecarga (énfasis en la palabra PARECIDO sin que implique que tienen la misma filosofía)
Otro detalle es que se recomienda adicionar en los métodos [HttpPost] el atributo [ValidateAntiForgeryToken] esto es para evitar inyección de código o cualquier otra artimaña, pueden investigar al respecto si lo desean.
Volvamos a nuestro Role Controller, para que este señor tenga un sentido en su binaria vida va a necesitar Views (o vistas) hay dos formas de crearlas una es al estilo desarrollador lomo plateado con botón derecho sobre la carpeta Views, en esta ocasión usaremos una de las facilidades que brinda .Net: Scaffolding, sigamos estos pasos:
1.- Para hacer Scaffolding de las vistas que necesitamos hacemos click derecho sobre el método del Controller que necesitemos y seleccionamos AddView casi al inicio del menú.
2.- En la siguiente pantalla dejemos las cosas como están, podríamos cambiar el nombre y otras propiedades pero no lo recomendaría, simplemente hagamos click en "Add"
Vamos a necesitar hacer scaffolding tambien para la creación del Rol, para ello repetimos los pasos 1 y 2 sobre cualquiera de los dos métodos que digan Create.
Si vemos la carpeta Views deberíamos tener una carpeta llamada Role (por el correcto balance del universo ni se les ocurra cambiarle el nombre) y dentro de esta carpeta los views para Index y Create
Editemos los views de la siguiente manera:
Index.cshtml
Create.cshtml
Detalles sobre estas dos vistas, si notan ven que ambas tienen un encabezado que indica: @model Microsoft.AspNet.Identity.EntityFramework.IdentityRole, esto conforma lo que se conoce como patrón Modelo Vista Controlador o MVC, vean tambien que en la vista de Create se manejan controles Razor para la inserción de datos: @Html.EditorFor(m => m.Name) indica que ese control en particular esta directamente relacionado con la propiedad Name del modelo y éste a su vez con el campo Name en el repositorio de datos correspondiente, como ven todo está estrechamente relacionado.
Continuemos con nuestro proyecto, ahora es el turno del AccountController, quien similar al RoleController ejerce las funciones de gestión de cuentas de usuarios. Acá escribiremos el siguiente código justo en el bloque de declaraciones antes del constructor.
ApplicationDbContext context;
y modificamos el constructor de la siguiente manera:
public AccountController()
{
context = new ApplicationDbContext();
}
Acabamos de crear el Contexto del AccountController que permitirá enviar la información recolectada en la vista hacia el repositorio de datos definido, en este caso los nativos de Identity.
Luego ubicamos el método Register y lo modificamos de la siguiente manera:
Lo que hicimos simplemente fue adicionar una lista desplegable que debe contener el nombre del Rol que se cargo en los Views que definimos previamente en el RoleController y el Name que aparece allí viene de la propiedad "Name" definida en el "RegisterViewModel" ¿Recuerdan?
Ahora para que esto último tenga sentido práctico para lo que deseamos, debemos hacer ajustes en las vistas.
Ubicamos en la carpeta de View del proyecto la sub carpeta Account y dentro el View Register.cshtml y justo encima del botón submit colocamos la lista desplegable Razor.
Volvemos al AccountController ya que tenemos una modificación más que hacer. Ubicamos el método Register (el asíncrono que tiene [HttpPost]) y modificamos, el método debería lucir de esta forma:
Simplemente invocamos al método del UserManager (del Identity) AddToRoleAsync que permite asociar los roles al usuario, luego veremos con detalle esto, otra cosa a tomar en consideración acá es que los métodos de creación de usuarios son siempre asíncronos ¿Pueden modificarse estos métodos para recibir mayor información que simplemente correo, nombre y rol? La respuesta es si.
Finalmente modificamos el View _Layout.cshtml, este View se ubica en la carpetas Views sub carpeta Shared, allí veremos algunos elementos como "Home", "About", "Contact" que no son otra cosa más que un menú de ejemplo, justo debajo del elemento "Contact" pegamos esta linea de código:
<li>@Html.ActionLink("Role", "Index", "Role")</li>
Y el menú debería lucir de esta forma:
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
<li>@Html.ActionLink("Role", "Index", "Role")</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
Y es hora de probar nuestra aplicación, presionemos Ctrl + F5 and RELEASE THE KRAKEN!
Al hacer click en Role, la aplicación debería mostrar la siguiente pantalla, que es el View Index
Al hacer click en el link "Crear Rol" debería mostrarse la pantalla de creación de Roles
Let's have some fun y creemos los roles de Manager and Sales Executive, luego validemos que se crearon de forma correcta en el Index de Roles
¿Y para que rayos creamos Roles si no los asignamos, bueno mis padawanes prosigamos a la creación/asginacion de roles a Usuarios y para esto, hagamos click en la opción "Register" en la esquina superior derecha al lado de "Log In" y se nos debería aparecer la siguiente pantalla
Hagamos la prueba de crear estos usuarios:
correo: jbrito@test.com
password: Jbrito1234$
Rol: Manager
correo: chernand@test.com
password: Chernand1234$
Rol: Sales Executive
Para finalizar, la parte divertida: Chequeemos en la Base de Datos
Roles creados
Usuarios asociados a roles
Y finalmente los usuarios creados
Bien, ésta fue la tercera de cuatro partes de un tutorial que considero fundamental para trabajar con seguridad integrada en Asp.Net con MVC 5 y Identity-Owin fuimos de lo básico a lo complejo, espero lo hayan disfrutado leyendo (y practicándolo) como yo haciéndolo.
Como siempre les digo: Happy Coding!!!
Comentarios
Publicar un comentario