Autenticación de Usuarios basada en Roles utilizando HTTPModules en ASP

March 21, 2018 | Author: Marco Antonio Monzón Lazcano | Category: Active Server Pages, Authentication, Internet Information Services, Databases, Http Cookie


Comments



Description

Autenticación de Usuarios basada en Roles utilizando HTTPModules en ASP .NET Personas que lo han encontrado útil: 30 de 42 - Valorar este tema Por Daniel Laco y Julieta Cozzi Descargar ejemplos de este artículo (120 KB). Contenido Introducción Autenticación de Usuarios por Roles Usuario No Autenticado Usuario Autenticado Conclusión Introducción Hoy en día, si existe algo crítico en todo sistema informático, es el tema de la seguridad; particularmente en las aplicaciones Web, donde nos enfrentamos a una gran cantidad de ataques de los mas diversos tipos. Una de las necesidades más comunes de estos sistemas, además de los mecanismos propios de seguridad, es poder contar con un mecanismo de autorización basado en Roles o Perfiles que permita al sistema verificar qué roles tienen permisos sobre qué recursos; qué opciones de menú configurar; o qué información mostrar en tiempo de ejecución. En esta nota explicaremos una implementación de este modelo de seguridad utilizando la infraestructura que nos brinda ASP .NET, mediante la utilización de HttpModules , validando los Roles y Usuarios almacenados en una Base de Datos. Principio de la página Autenticación de Usuarios por Roles El trabajo con roles no es un tema nuevo en el desarrollo de aplicaciones, y existen distintas formas de implementarlo. ¿Recuerdas cuando en ASP había que chequear la seguridad página por página? Por supuesto que existen varias alternativas para tratar el mismo problema; algunas más eficientes y escalables que otras. En ASP .NET esto está resuelto ya que en el Web.Config se pueden configurar los accesos a las diferentes secciones de nuestra aplicación; por ejemplo, en la siguiente porción de código se indica que todos los usuarios tienen acceso a “página.aspx”: < location path ="pagina.aspx"> < system.web > < authorization > < allow users ="*" /> </ authorization > </ system.web > </ location > Veamos ahora el ejemplo para entender la solución: .Volver al texto.NET.NET veremos en la sección de HttpModules todos los filtros que vienen programados y configurados cuando se instala .config de la aplicación. para esto veamos el ciclo de vida de las páginas en ASP .Pero. en un servicio de directorio como Active Directory o en alguna otra opción de almacenamiento. que a su vez la retorna al navegador que realizó la petición original (Ver Figura 1): Figura 1: Ciclo de vida de páginas ASP ..NET durante el proceso de cada petición. Más adelante trataremos este punto con mayor claridad. Primero debemos entender cómo funcionan y qué son estos HttpModules.NET tenemos la posibilidad de poder “engancharnos” en el ciclo de vida de una página. Dentro de este proceso. continúa cuando la petición es enviada a aspnet_isapi. roles y páginas cambian continuamente por programación.dll que es la que administra todo el flujo entre IIS y ASP .Web.FormsAuthenticationModule" /> < add name ="PassportAuthentication" type ="System. hay ocasiones en donde el escenario que se presenta es distinto. siendo necesario poder configurar dinámicamente el acceso a las páginas. < add name ="FileAuthorization" type ="System. Para atender a estos casos veremos una implementación de seguridad basada en HttpModules de ASP .NET.NET y de qué modo interactúan estos módulos con el ciclo de vida de estas páginas: El ciclo de una llamada en HTTP comienza en el IIS (Internet Information Server). los que manejan las diferentes configuraciones de seguridad. y por último la petición llega al HttpHandler. Este se ocupará del armado de la página y realizará la escritura del Html hacia el IIS. Una vez que el componente está programado. ésta pasa a través de los diferentes HttpModules configurados en la cadena.FileAuthorizationModule" /> Programar un HttpModule es sencillo.Web. < add name ="WindowsAuthentication" type ="System.Security.NET.Security. solo requiere implementar la interfaz IHttpModule y desde el código definir en cuáles eventos se va a responder. solamente es necesario agregar la entrada correspondiente en el . porque se almacenan en una base de datos.NET.Web. Los usuarios. en general.NET.NET. donde los roles (o perfiles) de los usuarios están almacenados en una base de datos. y la autorización es administrada con esta solución. por ejemplo. Estos filtros permiten “atender” diferentes eventos que dispara ASP .Web. entre ellos están.Security. es por demás interesante que utilicemos esta funcionalidad para nuestra solución de seguridad basada en roles.WindowsAuthenticationModule" /> < add name ="FormsAuthentication" type ="System. Cuando la petición ingresa en el circuito propiamente de ASP .Security. los HttpModules son filtros que se pueden programar e incluir en la configuración de la aplicación ASP ..PassportAuthenticationModule" /> . Si miramos en el archivo machine. Si con .config de . Identity. los mismos pueden encontrarse en la base de datos.Name . por ejemplo.Security. El método de autenticación estará basado en Forms. tiene distintas propiedades que permiten obtener diferentes datos de los usuarios. Es decir. En este ejemplo reemplazaremos directamente el Principal del HttpContext por una clase propia que implementa la interfaz IPrincipal. Roles o Perfiles: simplemente son los nombres de los distintos roles que se agregan al objeto principal.Principal. agregaremos métodos y propiedades útiles para nuestro modelo de seguridad.  Identidad ( Identity ): representa al usuario. Nos permite obtener el nombre del usuario autenticado en nuestro sistema. así como también otros datos que puedan ser de interés según las reglas del negocio. a saber (Ver Figura 2):     Usuarios: contiene todos los datos de los usuarios necesarios según las reglas del negocio de la aplicación y el identificador del rol al que pertenecen. Ahora bien. public class FormsPrincipal :IPrincipal. contaremos con una estructura mínima de 4 tablas.IPrincipal user. ¿De qué forma podemos tener información del usuario autenticado en cualquier punto de la aplicación? Una de las alternativas podría ser guardar información en la Session del usuario. además de tener las propiedades propias de la interfaz.Para comenzar tenemos una base de datos con los usuarios que acceden a nuestra aplicación. string username = user. PerfilesPaginas: contiene todas las páginas que utiliza cada rol. Figura 2. Perfiles: contiene todos los perfiles que se utilizarán en la aplicación y una descripción de los mismos. los roles de los mismos y las páginas del sistema. . nos quedará lo siguiente:  Principal: es un objeto que contiene información asociada al usuario actual. por ejemplo: System. Necesitamos además una clase que contenga la información del usuario y el componente que cumpla la función de HttpModule. su rol y su identidad. Al personalizar este objeto a nuestras necesidades. Paginas: contiene todos los nombres y URLs de las páginas del sistema. IMyAppPrincipal { private IIdentity _identity. Volver al texto. _Perfil ). string [] roles) { _identity = identity.AddPaginasToCache( perfil. } Cabe destacar que esta clase no está completa.Now. //Propiedad que utilizaremos para saber si el usuario tiene o no habilitado //el acceso a una determinada página public bool IsPageEnabled(string pageName) { return Perfiles. El paso siguiente es configurar y programar la autenticación basada en Forms: Agregamos la entrada en el web.UserCache. SeguridadEnAspNet. public FormsPrincipal( IIdentity identity. System. //Chequeo de usuario y contraseña SeguridadEnAspNet.Length > 0) // perfil vacío significa que no fue encontrado { //Invoca a componente que se encarga del Cache de los datos //en este caso de las páginas a las que el perfil tiene acceso SeguridadEnAspNet.. if (perfil.AddMinutes(60). perfil.Perfiles.GetPaginas(perfil) . false . } //.Now.IsPageEnabled( pageName. hemos agregado los comentarios correspondientes a los efectos de clarificar la funcionalidad de cada línea de programación: private void btnSubmit_Click(object sender. private string _Perfil.FormsCookiePath).Text.private string [] _roles.Text. .System.Usuario oUser = new SeguridadEnAspNet.HttpContext.Web. // version user.Current ). password).config < authentication mode ="Forms"> < forms loginUrl ="Login. // guardo el perfil del usuario FormsAuthentication. } //.GetPerfil(user. // Crea un ticket de Autenticación de forma manual. _Perfil = Perfil..aspx" timeout ="20"/> </ authentication > Y programamos nuestra página Login. solo se reprodujo parcialmente con el propósito de visualizar el objeto principal y cómo hemos implementado la interfaz IPrincipal..aspx.Usuario().EventArgs e) { string user = txtUser. this. DateTime.. // donde guardaremos información que nos interesa FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(2. string perfil = oUser. _roles = roles. DateTime. string password = txtPassword. Web. using System.Security.Importante!! no usar el RedirectFromLoginPage // Para que se puedan usar las Cookies de los HttpModules Response. using System.GetRedirectUrl(user. crypTicket). Veamos ahora la programación de nuestro HttpModule.Add(authCookie).AuthorizeRequest += new EventHandler(this.Encrypt(authTicket).Cookies.false)).Style["display"] = "".AuthenticateRequest += new EventHandler(this.// Encripto el Ticket. Response.Redirect( FormsAuthentication.Principal.Security.Web. } Sólo hemos reproducido el código correspondiente al método del acceso. } else // Muestro mensaje de error tblWarning.FormsCookieName. using System. // Redirecciono al Usuario . oHttpApp.AuthenticateRequest). namespace SeguridadEnAspNet { /// <summary> /// Modulo de Administración de la Seguridad /// Seguridad basada en Forms /// </summary> public class CustomAuthenticationModule : IHttpModule { public CustomAuthenticationModule() {} /// <summary> /// Inicializa el HTTPModule y asigna los EventHandlers a cada Evento /// Esta es la parte donde se define a que eventos va a atender el HttpModule /// </summary> /// <param name="oHttpApp"></param> public void Init(HttpApplication oHttpApp) { // Se Registran los Manejadores de Evento que nos interesa oHttpApp. // Creo la Cookie HttpCookie authCookie = new HttpCookie(FormsAuthentication.AuthorizaRequest). string crypTicket = FormsAuthentication. la clase completa la puedes consultar en el código adjunto a esta nota. using System. } public void Dispose() {} /// <summary> /// Administra la autorización por Request /// </summary> /// <param name="sender"></param> /// <param name="e"></param> . Identity is FormsIdentity) { //Traigo el Rol que esta guardado en una Cookie encriptada FormsIdentity id = (FormsIdentity)HttpContext.Identity.IsAuthenticated) { if (HttpContext.Length > 0 ) rol= ticket. EventArgs e) { if (HttpContext.HttpContext. EventArgs e) { if (HttpContext.Identity.User.User = new SeguridadEnAspNet.User is MyApp.Current.IsAuthenticated) { if (HttpContext.Current.Ticket. } } } } /// <summary> /// Autentica en Cada Request /// </summary> /// <param name="sender"> HttpApplication </param> /// <param name="e"></param> private void AuthenticateRequest(object sender.Decrypt(userData).Web.Current.Value.Path) ) HttpContext.Current.Current.Request.aspx").Security.Current.Server.Transfer( "NoAutorizado. //Se crea la clase Principal y se asigna al CurrenUser del Contexto HttpContext. if( userData.Seguridad.FormsCookieName.Request.Current.Current.FormsPrincipal(_identity.Current.Current.FormsPrincipal) { MyApp. } } . //Se verifica si el Perfil del usuario tiene autorización para acceder a la página if ( !principal.FormsPrincipal principal = (SeguridadEnAspNet.private void AuthorizaRequest( object sender.Current. string rol="". ticket = FormsAuthentication.User != null) { //Si el usuario esta Autenticado if (HttpContext. string cookieName = System.Web.IsPageEnabled( HttpContext.Seguridad.User.Identity.Cookies[cookieName]. perfil).User.User != null) { //Si el usuario esta Autenticado if (HttpContext.User.FormsAuthentication.UserData. FormsAuthenticationTicket ticket = id.FormsPrincipal) HttpContext. string userData = System.Current.User. y con esta información creamos la claseFormsPrincipal. ¿Qué ocurre cuando un usuario realiza la petición de una página de nuestra aplicación? Principio de la página Usuario No Autenticado Si el usuario no está autenticado aún. realiza el proceso normal de autenticación por Formularios (Forms).Modulo de Autorización -. Con esta configuración. en cualquier parte de nuestro código se puede hacer lo siguiente: SeguridadEnAspNet. para administrar la seguridad de la aplicación.aspx" timeout ="20" /> </ authentication > < authorization > < deny users ="?" /> </ authorization > //.IsDataVisible("txtNombreControl" )) txtNombreControl. Para esto. Si bien la funcionalidad que estamos mostrando se aplica para páginas. en este caso.Visible = false. indicándole que la página de autenticación es “Login.aspx” y que los usuarios anónimos no tienen acceso a nuestra aplicación. en caso de que no esté autorizado. el primer evento que se dispara es el AuthenticateRequest. también se puede extender a la clase que implementa IPrincipal y agregarle otros métodos que permitan.CurrentUser.CurrentUser. Principio de la página Usuario Autenticado Si el usuario está autenticado.CustomPrincipal) HttpContent.> < httpModules > < add type ="SeguridadEnAspNet.. Este objeto será posteriormente asignado al HttpContext. Lo que hace es verificar si el usuario tiene acceso a la página que está solicitando. <! -. chequear a qué datos de una página tiene acceso el rol.CustomPrincipal user = (SeguridadEnAspNet.. por ejemplo.CustomAuthenticationModule. El evento que se dispara a continuación es el AuthorizaRequest. . para obtener los roles (o perfiles) del usuario desde una cookie.} }//AuthenticateRequest } //class } //namespace Una vez que tenemos nuestro módulo de seguridad (HttpModule: CustomAuthenticationModule). la aplicación lo derivará a una página de error con el mensaje correspondiente. se deberá referenciar en el archivo de configuración de nuestra aplicación como se muestra a continuación: < authentication mode ="Forms"> < forms loginUrl ="Login. También estamos definiendo el HttpModule que utilizaremos. if ( ! user. SecurityModules" name ="CustomAuthenticationModule" /> </ httpModules > De esta forma estamos configurando el modo de autenticación por formularios.
Copyright © 2024 DOKUMEN.SITE Inc.