Ir al contenido principal

Seguridad en ASP.Net Identity 2.0 con Webforms Parte 4 (Accesos a Views mediante CustomFilters + Introducción al Entity Framework 6)




Este post viene gracias a la siguiente publicación creada por Mahesh Sabnis.

Saludos colegas desarrolladores, espero que se encuentren bien y que los usuarios y los testers no los hayan maltratado mucho, este nuevo post es la cuarta y última parte de una serie que realicé anteriormente, las cuales recomiendo ver antes: acá la parte 1, acá la parte 2 y acá la parte 3.

Les recomiendo enormemente que echen un vistazo al menos a la tercera parte de la serie de posts sobre seguridad para que comprendan mejor como se manejan la administración de Roles en Asp.Net MVC5, de hecho emplearé la aplicación de ejemplo que se creó en dicha entrada.

Antes que nada crearemos una tabla de prueba, llamada "Productos" en el manejador de BD de su preferencia, yo usaré MSSQL Server. Acá pueden ver los detalles de la tabla.



El autor original prefirió ser un poco desarrollador lomo plateado y creó a pulmón el controller y las vistas del proyecto, por supuesto que no está mal y en el post anterior hicimos ya algo similar, yo prefiero aprovechar las bondades de .Net y trabajar con Entity Framework 6, así que tienen un 2 x 1, aplicarán filtrados por roles y tendrán una pequeña introducción al Entity Framework 6, Nada mal ¿Verdad?

Continuemos, antes que nada una pequeña recomendación, a mi me gusta trabajar con cierto orden en el código a pesar que mi escritorio es un desastre, así que les recomiendo crear una carpeta dentro del proyecto con un nombre que indique allí irá un modelo de datos, luego recurrimos al viejo truco del botón derecho del mouse sobre la carpeta (o el proyecto si son un grupo de pandilleros del código) y seleccionamos Agregar -> Nuevo Elemento



En la pantalla que aparecerá rápidamente seleccionamos en el lado izquierdo Datos y del listado de Opciones ADO.NET Entity Data Model, especificamos un nombre para la entidad (Siempre háganlo en el nombre de los estándares) y hacemos click en "Agregar"



Luego veremos al siguiente Wizard:



No ese Wizard, disculpen, este Wizard, donde seleccionaremos la primera opción (EF Designer desde base de datos) y click en "Siguiente".


La siguiente pantalla aparecerá.



En esta nueva pantalla seleccionaremos la cadena de conexión que estamos empleando, yo por ejemplo uso la Default (configurada desde el post 3 de seguridad con Identity), o simplemente creamos una nueva haciendo click en "Nueva Conexión" (Nada nuevo que explicar ya que es la misma forma de crear cadenas de conexión desde la época antediluviana) hay dos opciones que aparecen ya que por razones didácticas coloqué el usuario y la contraseña para la BD del ejemplo, una pregunta si desea adicionar esa información en la conexión para el Entity o no, yo por razones diversas diré que si.

Lo último que aparece en esta pantalla es si desean guardar la configuración en el Web.Config y un nombre para esta entrada, preferiblemente dejen marcado el Checkbox y verifiquen que el nombre no les cause conflicto con algún objeto que pueda llamarse igual, luego presionamos "Siguiente".

Tenemos ahora esta otra pantalla.



En la siguiente pantalla podremos seleccionar los objetos de Base de Datos que nos interese, bien sean: Tablas, Vistas o Funciones + Stored Procedures, desplegamos la lista de objetos en Tablas y seleccionamos la tabla que nos interesa en particular: Productos y verificamos el Espacio de Nombres del Modelo para que no coincida con otro objeto en el proyecto.

Atención con un detalle en esta última pantalla, ven que hay dos Checkboxes activos, uno que dice Poner en Plural o Singular... y otra que dice Incluir columnas... ésta última esta seleccionada ya, así que no hay problema, pero con la otra que pregunta sobre Plurales o Singulares pasa lo siguiente: Yo siempre prefiero seleccionarla, pero como .Net es originalmente de idioma Inglés (oh sorpresa) esta opción de nombre de objetos plurales tiene especial significado con nombres en Inglés, por ejemplo si la tabla la hubieramos llamado "Products" los objetos creados luego de este wizard se llamarían simplemente como "Product", por razones de estándares se recomienda que esto sea así, en español si reconoce algunas cosas como sigulares o plurales y enfatizo ALGUNAS, con esto aclarado hacemos click en el botón "Finalizar".

Bien, luego de culminado el wizard, se nos mostrará una pantalla similar a un diagrama de entidad-relación con el objeto creado como ésta:



En este caso se muestra un modelo de la tabla Productos, como seleccionamos la opción de Plural a Singular vemos que nuestro objeto se llama "Producto" tal cual.

Curioseando un poco más veamos que hay dentro de ese Modelo de Datos con extensión edmx, despleguemos hasta ver un objeto llamado TestModel.tt, despleguemos nuevamente y veamos que hay una clase llamada Producto.cs.



Si hacemos doble click sobre Producto.cs veremos el siguiente código



Vean que tiene una advertencia que dice que si se toca el código se autodestruirá el proyecto, bueno nada que temer, eso si NO es recomendable cambiarlo ya que si lo hacen cualquier cosa que hagan se sobreescribirá cada vez que se actualice el modelo, si quieren algún comportamiento aplicando algún atributo u otra propiedad adicional, entonces deberán hacer una extensión del modelo, el cual prontamente les enseñaré como hacer.

Ya con nuestro modelo creado podemos entonces crear nuestro controller para Productos directamente del modelo, y esto se hace nuevamente con el viejo truco del botón derecho del mouse sobre la carpeta Controllers del proyecto Agregar -> Controller



Y debe aparecer la siguiente pantalla



En esta pantalla seleccionamos la opción: "Web API 2 Controller with views, using Entity Framework" y el botón "Add"

Se nos mostrará una nueva pantalla con una lista desplegable de Modelos.



Seleccionamos el que nos interesa: Producto, en la lista desplegable de Data Context validamos que el Data Context sea justo el que creamos para el Entity Data Model (SecurityTestEntities) y cambiamos el nombre a ProductoController, preferiblemente las otras opciones dejarlas como están.

No es necesario hacer click en el Checkbox Use async controller actions, esto es para actions particulares y en este momento no necesitamos eso. luego de hacer click en
"Add" deberíamos tener...

Ups, pues podriamos tener un error como este



Nada que temer, ese error es muy común que se presente, simplemente hacemos lo que el mensaje nos dice: "Try Rebuilding the Project", así que nos resignamos y aceptamos, cancelamos la pantalla de creación del controller, compilamos el proyecto y nuevamente repetimos los pasos para adicionar el controller.

¿Recuerdan esa palabrita rebuscada que empleamos en el post anterior (link al post) esa llamada Scaffolding? Bueno justo acabamos de hacer un Scaffolding del modelo Producto y si validamos en la carpeta controller deberíamos tener enotnces un objeto llamado ProductoController con sus respectivos métodos y en la carpeta Views del proyecto una nueva llamada Producto con cinco Views (Create, Delete, Details, Edit e Index) que son los actions estándares dentro de un Controller MVC

Ahora vamos con el tópico de interés del post: Adicionar CustomFilters.

Para esto debemos crear primero en la carpet Views, sub carpeta Shared un View vacío, solo lo nombramos como AuthorizeFailed y hacemos click en "Add"



Luego modificamos el View recién creado con este código:



En el proyecto creamos una nueva carpeta llamada CustomFilters y adentro una nueva clase llamada también CustomFilters, modificamos el archivo con el siguiente código:



Vayamos ahora al ProductoController y hagamos los siguientes cambios:

1.- Referenciemos al CustomFilter creado antes así:
using TestRolesMVC_2.CustomFilters;

2.- Ubiquemos el método Create() (que no tiene atributo [HttpPost]) y hagamos este cambio:
        // GET: Producto/Create
        [AuthLog(Roles = "Manager")]
        public ActionResult Create()
        {
            return View();
        }

Con ello deberíamos decir que solo el Manager puede crear.

3.- Ubiquemos el método Details() y hagamos este cambio:

         // GET: Producto/Details/5
        [AuthLog(Roles = "Sales Executive")]
        public ActionResult Details(int? id)
        {
            if(id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Producto producto = db.Productos.Find(id);
            if(producto == null)
            {
                return HttpNotFound();
            }
            return View(producto);
        }

Con ello deberíamos decir que solo el Sales Executive puede ver los detalles.

Ahora modificamos el View _Layout.cshtml,y pegamos esta linea de código:

 <li>@Html.ActionLink("Producto", "Index", "Producto")</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>
<li>@Html.ActionLink("Producto", "Index", "Producto")</li>
                </ul>
                @Html.Partial("_LoginPartial")
            </div>

Presionemos Ctrl + F5 y hagamos Log In con el usuario jbrito@test.com (Creado del post anterior) y vamos a crear productos, cuando tengamos 1 o 2 productos hagamos click en la opción Details dentro del Index, y la siguiente pantalla debería aparecer:



Ahora cambiemos el Rol al usuario Sales Executive chernand@test.com, click en el menú Producto y click en Opción Details dentro del listado de productos, deberíamos poder visualizar el detalle del producto, regresemos a la pantalla Index de Producto y hagamos Click en el Link "Create" y la siguiente pantalla debería aparecer


Como pueden apreciar el uso de la seguridad integrada con Roles es muy extenso y ahorra muchas horas de código con unos simples y sencillos pasos. Espero hayan disfrutado de esta última entrada de este complejo e interesante tutorial para Seguridad en ASP.Net Identity 2.0 con Webforms.

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...