¿Como Crear Seguridad Personalizada en MVC?
Seguridad Personalizada
La capa de seguridad de MVC es una capa independientemente de las demás capas de un Proyecto de un MVC
Podemos añadir o quitar el capa de seguridad en cualquier momento de la creación del proyecto sin afectar a la funcionalidad del proyecto.
Lo que sirve la capa de seguridad es limitar el permiso de acceso a cierta página del proyecto por diferente role.
SOLUCIÓN RÁPIDA (copia código y Ya está)Preparación
la capa de seguridad se implementa sobre un proyecto de MVC funcional.
Así que, para la mostración de la implementación de la capa de seguridad, creamos un proyecto de ASP.NET con plantilla de MVC.
Si hacemos click sobre ese link nos lleva directamente al vista de la lista de empleado sin ningun problema.
Ejemplo de implementar la capa de seguridad
Lo que vamos a hacer es limitar el permiso de acceso al Vista de LISTADOEMPLEADO, solo el usuario que esta iniciado sesion y tiene el permiso de ADMIN puede entrarPaso que necesitamos hacer
- 1º paso crear controlador manage
- 2º paso configurar el fichero global.asax
- 3º paso crear AutorizarAttribute
- 4º paso implementar el AutorizarAttribute en el controlador o vista que quiere limitar el permiso de acceso
- 5º paso crea vista parcial para cerrar sesión
1º PASO crear controlador Manage
Creamos un controlador de manage(el nombre de controlar puede ser persalizado) lo utilizamos para manejar el login del usuario.
- GET: LOGIN (mostrar la vista de login para iniciar sesion)
- POST:LOGIN(realizar autenticacion de cuenta y redirecionar al pagina del lista empleado)
- GET: ERRORACCESO(que se devuelve una vista que muestra el mensaje de que no tienes permiso de acceso de la pagina)
- GET: CERRARSESION(es una ACTION que utiliza para cerrar cession del usuario)
GET:Login (mostrar la vista de login para iniciar sesion) .
En la vista del login contiene un formulario para enviar los datos del usuario y password de formato POST.
POST:Login(realizar autenticacion de cuenta y redireccionar al pagina del lista empleado).
En el posta del Login recibimos el nombre de usuario y password Primero realizamos la comprobacion de que si existe el usuario o no .
Para facilizar el proceso de comprobacion aquí utilizamos un “IF” y solo con la cuenta del admin y del empleado, pero lo mas completo de realizar una comprobacion es conectar el proyecto con un BBDD y hacer la comprobacion con la tabla User.
Si el usuario y password que hemos recibido conincite con el admin o empleado añadimos el role y idempleado que pertenece a variable “role” y “idempleado” .
Después de la comprobación, si existe el usuario crea un TICK para almacenar los datos necesarios para crear una cookie.
Un TICK necesita siguientes datos.
- Numero de versión (de ejemplo ponemos 1)
- Nombre de identidad
- Fecha y hora de inicio
- Fecha y hora de expirar (indicar cuanto tiempo va a durar este TICK, puede ser minutos, horas o días)
- Persistente
- Un dato de tipo STRING que deseamos guardar para que podemos recuperar luego (en nuestro ejemplo guardamos el “role” del usuario)
Despues lo ciframos el TICK y lo guardamos en un COOKIE llamado “Usuario”.
Y despues hacemos un redireccion a la pagina de ListaEmpado del controlador Empleado.
El cookie que hemos creado lo utilizamos luego en la Golbal.asax para crear la sesion.
GET: ErrorAcceso(devulve una Vista que se muestra el mensaje de que no tienes permiso de acceso de la pagina).
GET: CerrarSesion(se utiliza para cerrar cesion del usuario y redirecciona al pagina index del Home).
2º PASO Configurar Global.asax
Lo que hacemos en goblal.asax es meter el cookie del “Usuario” que hemos creado en el HTTPCONTEXT.CURRENT.USER.Vamos a necesitar utilizar la siguiente libreria.
3º PASO crear AutorizarATTRIBUTE
Es una clase que esta heredada del AUTHORIZEATTRIBUTE .El nombre de” Autorizar” es personalizable, pero es obligatorio que termina con “Attribute”.
Esta clase lo utilizamos para comprobar si el usuario esta autentificado o no y también podemos limitar el permiso de acceso de cierta pagina.
Por ejemplo, ahora vamos a limitar que, solo el usuario que tiene role de ADMIN puede entrar en la página de LISTAEMPLEADO.Librería que necesitamos.
4º paso implemetar el el Attribute Autorizar en el controlador o vista que quiere limitar el permiso de acceso
primero hacemos el using del carperta Attribute.
Para implementar la autenticación solo tenemos que añadir el [Autorizar] por encima del ACTION o CONTROLADOR que deseamos implementar la autenticación.
[Autorizar](es el nombre de clase de autenticación que hemos creamos) por defecto se omite el Attribute.5º paso crea vista parcial de cerrar sesion
Tenemos que crear una Vista Parcial en el menú de navegación para que podemos cerrar sesión después iniciar sesión.
El menú de navegación suele estar en el LAYAOUT así que para crear la vista parcial en la carpeta SHARED para que podamos llamar desde LAYOAUT.Usamos un “if” para que solo se muestre esta vista parcial cuanto el usuario esta autenticado.
Y contiene una LINK que llama el método que hemos creado ante en el controlador de manager que sirve para cerrar sesión.
COMPROBACION
Ejecutamos el Proyecto, hacemos clic sobre el LINK del LISTAEMPLEDODespués de iniciar sesión nos a dejado entrar en la página de lista empleado y también nos muestra la opción de cerrar sesión.
Ahora cerramos sesión y iniciamos de nuevo con la cuenta de Empleado.
Podemos ver que no tenemos permiso de acceder a la página del listado empleado .
Posible Problema
Con la configuración que hemos hecho anteriormente, hay un problema sobre el POST de LOGIN.Cuando hacemos clic sobre link de “Perfil” nos pide que iniciemos la sesión.
En la clase de AUTORIZARATTRIBUTE
Primero capturamos el ACTION y CONTROLADOR que el usuario desea ir (capturar el usuario en que LINK ha hecho click) utilizando el ROUTEDATA.VALUE.En el POST DE LOGIN (controlador de MANAGE)
En el POST de LOGIN recupera el ACTION y CONTROLADOR que hemos guardado y redireccionamos dinámicamente a la página que el usuario deseado ir (en la siguiente imagen hay un “if” porque el ACTION de DETALLAEMPLADO necesita recibir un IDEMPLEADO)Comprobación:
Solución Rápido (Sin preguntar porque COPIA y PEGALO siguiente código a tu PROYECTO DE MVC):
VolverCrear un Controlador llamado Manage
Las librerías que necesita para el ManageController
using System.Web.Mvc;
using System.Web.Security;
Y copia siguiente código y pégalo dentro del ManageController
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(string usuario, string password)
{
string role = null;
int idempelado=0;
//esta parte puede cambiarlo por un metodo que comprueba si el usuario y password que recipido coincide con tu BBDD o no
if (usuario.ToUpper() =="ADMIN" && password.ToUpper()=="ADMIN")
{
role = "ADMIN";
idempelado = 4;
}
else if (usuario.ToUpper() == "EMPLEADO" && password.ToUpper() == "EMPLEADO")
{
role = "EMPLEADO";
idempelado = 1;
}
if (role != null)
{
FormsAuthenticationTicket ticket =
new FormsAuthenticationTicket
(
1,
idempelado.ToString(),//este el valor que vamos a guarda en HttpContext.Current.User.Identity.Name
DateTime.Now,
DateTime.Now.AddMinutes(10),
true,
role //este es variable que guarda el valor de role
);
string datos = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie("Usuario", datos);
Response.Cookies.Add(cookie);
string action = TempData["action"].ToString();
string controlador = TempData["controlador"].ToString();
if (action== "DetalleEmpelado")
{
return RedirectToAction(action, controlador, new { idEmp = idempelado });
}
else
{
return RedirectToAction(action, controlador);
}
}
else
{
ViewBag.mensaje = "Usuario/Password incorrecto";
return View();
}
}
public ActionResult ErrorAcceso()
{
return View();
}
public ActionResult CerrarSesion()
{
HttpContext.User = null;
FormsAuthentication.SignOut();
HttpCookie cookie = Request.Cookies["Usuario"];
cookie.Expires = DateTime.Now.AddMinutes(-30);
Response.Cookies.Add(cookie);
return RedirectToAction("Index", "Home");
}
Crear Vista de LOGIN y ERRORACCESO
VISTA LOGIN:
Copia siguiente código y sustituir todos los contenitos de la Vista de LOGIN
@{
ViewBag.Title = "Login";
}
<h2>Login de Usuario</h2>
@using (Html.BeginForm())
{
<div>
<label>Usuario :</label>
<input type="text" class="form-control" name="usuario" placeholder="Nombre de Usuario" />
</div>
<div>
<label>Password :</label>
<input type="password" class="form-control" name="password" placeholder="Clave de acceso" />
</div>
<br />
<div>
<button type="submit" class="btn btn-success">Login</button>
</div>
}
<h1 style="color:red">@ViewBag.Mensaje</h1>
VISTA ERRORACCESO:
Copia siguiente código y sustituir todos los contenitos de la Vista de ERRORACCESO
@{
ViewBag.Title = "ErrorAcceso";
}
<h2>ErrorAcceso</h2>
Crear Vista Parcial de CERRARSECION en SHARED
Copia siguiente código en tu Vista de CERRARSECION
@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
<li>@Html.ActionLink("Cerrar sesion","CerrarSesion","Manage")</li>
}
En tu LAYAOUT añadir siguiente código en tu menú de navegación para mostrar la opción de cerrar sesión
@Html.Partial("_CerrarSesion")
Crear una carpeta Attribute y crear una clase con nombre de AutorizarAttribute
Elimina todos lo que tiene dentro del AutorizarAttribute copia siguiente código y pegarlo en AutorizarAttribute
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace post_Segurida_MVC.Attribute
{
public class AutorizarAttribute: AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
string controladorOrigen = filterContext.RouteData.Values["controller"].ToString();
string actionOrigen = filterContext.RouteData.Values["action"].ToString();
if (filterContext.HttpContext.Request.IsAuthenticated)
{
GenericPrincipal user = (GenericPrincipal)HttpContext.Current.User;
// aqui se puede un if para que limitar el acceso por role
//if (user.IsInRole("ADMIN") == false)
//{
// //nos lo llevamos a sin acceso
// RouteValueDictionary ruta = new RouteValueDictionary(new { Controller = "Manage", action = "ErrorAcceso" });
// filterContext.Result = new RedirectToRouteResult(ruta);
//}
}
else
{
filterContext.Controller.TempData["action"] = actionOrigen;
filterContext.Controller.TempData["controlador"] = controladorOrigen;
RouteValueDictionary rutalogin = new RouteValueDictionary(new { controller = "Manage", action = "Login" });
filterContext.Result = new RedirectToRouteResult(rutalogin);
}
}
}
}
Configurar Fichero GLOBAL.ASAX
copia siguiente código en tu Fichero de GLOBAL.ASAX
copia este método después del método de Application_Start
public void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["Usuario"];
if (cookie != null)
{
string datos = cookie.Value;
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(datos);
string role = ticket.UserData;
GenericPrincipal principal = new GenericPrincipal(new GenericIdentity(ticket.Name), new string[] { role });
HttpContext.Current.User = principal;
}
}
Ultimo paso, aplicar el [Autorizar] en cualquier ACTION CONTROLADOR que quiere aplicarse la autenticación de seguridad.
Con esto cuando el usuario quiere acceder al ACTION que has aplicado la autenticación el proyecto va ha pedir que primero se inicia la sesión.
Si tiene cualquier duda vuelva al Principio de este BLOG Y léalo otra vez Paso a Paso
Volver a PrincipioAutor: YIBING JIN
Curso: Microsoft MCSA Web Applications + Microsoft MCSD App Builder + Xamarin
Centro: Tajamar
Año académico: 2019-2020
Linkedin Repository GITHUB



























































