He creado una clase que nos permite guardar a un usuario en sesión de manera práctica.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Web.Security;
namespace Helper
{
public class SessionHelper
{
public static bool ExistUserInSession()
{
return HttpContext.Current.User.Identity.IsAuthenticated;
}
public static void DestroyUserSession()
{
FormsAuthentication.SignOut();
}
public static int GetUser()
{
int user_id = 0;
if (HttpContext.Current.User != null && HttpContext.Current.User.Identity is FormsIdentity)
{
FormsAuthenticationTicket ticket = ((FormsIdentity)HttpContext.Current.User.Identity).Ticket;
if (ticket != null)
{
user_id = Convert.ToInt32(ticket.UserData);
}
}
return user_id;
}
public static void AddUserToSession(string id)
{
bool persist = true;
var cookie = FormsAuthentication.GetAuthCookie("usuario", persist);
cookie.Name = FormsAuthentication.FormsCookieName;
cookie.Expires = DateTime.Now.AddMonths(3);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, id);
cookie.Value = FormsAuthentication.Encrypt(newTicket);
HttpContext.Current.Response.Cookies.Add(cookie);
}
}
}
Métodos que implementa
A continuación explico que hace cada método.
-
ExistUserInSession, verifica si el usuario actual se encuentra en sesión o no.
-
DestroyUserSession, elimina la sesión actual del usuario.
-
GetUser, obtiene el ID del usuario actual en sesión.
-
AddUserToSession, guarda el ID de nuestro usuario en sesión.
Como implementarlo
Tenemos nuestra lógica para hacer una atentificación, los pasos para implementar mi clase sería la siguiente:
-
Crea un nuevo proyecto ASP.NET MVC y elige sin autenticación, aparentemente no está funcionando cuando trabajas con la autenticación por default de ASP.NET.
-
En el webconfig debemos agregar dentro de las etiquetas
```: ``` -
Realiza tu algoritmo para auntentificarte.
-
Si el usuario ha pasado la validación, guarda su ID con el método AddUserToSession
``` SessionHelper.AddUserToSession(id.ToString()); ``` -
Listo, ya tenemos al usuario en sessión.
Restringir acceso
He creado 2 filtros (custom atrributes) para dar comportamiento a nuestro controladores y/o acciones, es decir que cuando el usuario visite "X" controlador, previamente este debe realizar lo que especifiquemos en los filtros.
using Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace WebApplication1.Tags
{
// Si no estamos logeado, regresamos al login
public class AutenticadoAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (!SessionHelper.ExistUserInSession())
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Login",
action = "Index"
}));
}
}
}
// Si estamos logeado ya no podemos acceder a la página de Login
public class NoLoginAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (SessionHelper.ExistUserInSession())
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Inicio",
action = "Index"
}));
}
}
}
}
- Crean dentro de su proyecto una carpeta llamada tags, o el nombre que gusten y copian el código de arriba.
- No se olviden cambiar el namespace para mantener un orden, en mi caso el namespace se llama WebApplication1.Tags
Que hace cada clase
- AutenticadoAttribute: hace una validación usando el método ExistUserInSession de la clase SessionHelper para preguntar si el usuario se encuentra logeado, y si la condición fuera falsa, lo redirecciona al controlador y acción que especiquemos. En mi caso he puesto controlador Login y acción index.
- NoLoginAttribute: esta clase la vamos a usar para que nuestro usuario, una vez que este logeado/autenticado, no pueda volver al controlador del login.
¿Como lo implemento?
Existen 2 formas de implementarlo, a nivel del controlador o de una acción especifica.
[Autenticado]
public class DefaultController : Controller
Nuestro tag se ejecutará al nivel de todo el controlador
[Autenticado]
public ActionResult Index()
Nuestro tag se ejecutará solo para la acción especificada.