Ir al contenido principal

Seguridad en ASP.Net Identity 2.0 con Webforms Parte 3 (Manejo de Roles)


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

Entradas populares de este blog

Como trabajar con decimales en ASP.Net MVC 5

Saludos a todos, este blog viene como una mezcla de varias cositas, es un experimento ya que peculiarmente he notado que casi no hay blogs dedicados a tips de programación de .Net en español y ciertamente la barrera de idiomas afecta de alguna manera u otra al desarrollador que busca una solución a sus problemas y la otra vertiente es que simplemente deseo ayudar, ayudar a quienes duran horas o días estancados en problema que quizás se podía resolver en pocas líneas de código, así que ¿Por qué no compartir las experiencias vividas para que otros no tengan tan cuesta arriba resolver alguna dificultad? Esta es mi primera entrada y espero que la disfruten. La pesadilla de todo desarrollador, trabajar con elementos globalizados como fechas y números con decimales, como todos bien saben este siempre es un tema que siempre trae algún que otro problema y que incluso puede quitar horas o días resolverlo, lo bueno es que existen miles de soluciones, algunas requieren líneas de cód...

Seguridad en ASP.Net Identity 2.0 con Webforms Parte 1

¡Saludos colegas desarrolladores y afines! En esta ocasión quiero compartir con Ustedes un pequeño tutorial para trabajar con ASP.Net Identity 2.0 en Webforms. Este creo que será quizás uno de los más complicados de hacer, así que tenedme paciencia. Planeo hacer de esta entrada la primera de varias partes. Como siempre me gusta indicar de donde me basé para escribir el post y fue de ACÁ  hay que dar el reconocimiento a la autora original: Raquel Soares De Almeida, es lo justo, claro yo simplemente digiero un poco el post y lo entrego a Ustedes con algunos detalles que el autor original pudo obviar por razones diversas. En este post en particular voy a ir a lo básico, crear el proyecto desde cero. 1.- Comenzamos con el clásico menú Archivo -> Nuevo -> Proyecto. 2.- Continuamos con la siguiente pantalla donde simplemente seleccionamos bajo la opción de plantillas a la izquierda Visual C#, luego Web y por último ASP.Net Web Forms Application (...

Seguridad en ASP.Net Identity 2.0 con Webforms Parte 2 (Owin el primo raro de Identity)

Este post es la segunda parte de una serie que planeo dedicar a ASP.Net Identity 2.0, como el post anterior este post está basado en ÉSTE  y fue creado por: Raquel Soares De Almeida. La razón de hacer una recopilación de este tema basado en algo ya publicado es que el post original esta en Ingles y quizás a algunos se le complique por la barrera del idioma, otra razón es que yo adiciono pequeños detalles que considero necesario reflejar y lo último es que son necesarias estas dos primeras partes para futuras publicaciones que verán acá prontamente, como aplicar filtrados por roles y asignar roles a usuarios, con esto aclarado comencemos nuestro post. Todos tenemos un primo raro que es algo excéntrico, Identity tiene el suyo y tiene hasta nombre, se llama Owin, el primo Owin.  El primo Owin es una capa intermedia basada en cookies mediante forms. Realmente es muy pero muy interesante, Owin combinado con Identity hacen muy bien la tarea de darnos la seguridad ne...