La protección de las aplicaciones es un elemento que no se puede dejar por fuera cuando se elabora un sistema. Cada parte o elemento de código que protege nuetra aplicación debe ser cuidadosamente seleccionado y elaborado.
Una de las cosas comunes con las que nos topamos en asp.net cuando deseamos trabajar con usuarios, es con la necesidad de poder redireccionarlos a los distintos elementos o páginas dependiendo del rol. Pues precisamente eso es lo que haremos, vamos a trabajar con el Web.config de nuestra aplicación y le añadiremos unas pequeñas líneas de código para lograr dar un poco mas de seguridad al sistema y sobre todo lograr el redireccionamiento.
Así que veamos como logramos lo deseado:
Como bien sabemos el web.config nos permite manejar muchos elementos dentro de asp.net, muchos de ellos relacionados con la seguridad, asi como tambien nos brinda la posibilidad de poder personalizar los elementos para poder adaptarlo a nuestras necesidades. Así que, basandonos en el principio de que podemos personalizar el web.config, entonces crearemos una sección personalizada, que será la que utilicemos para manejar el redireccionamiento:
Nuestro primer paso será ir a nuestro web.config y buscamos las siguientes líneas:
<configuration>
<configSections>
</sectionGroup>
</sectionGroup>
</sectionGroup>
Y luego de ellas definiremos una nueva sección
<section name="loginRedirectByRole" type="crabit.LoginRedirectByRoleSection" allowLocation="true" allowDefinition="Everywhere" />
El section name corresponde al nombre de nuestra nueva sección
Type corresponde al nombre de la clase (que pronto realizaremos) y que será la encargada del Redirect
Como estamos trabajando dentro de la seccion de configuración una vez definidad nuestra sección personalizada debemos cerrar esta sección
</configSections>
Por lo que nuestro web.config debería lucir de la siguiente forma
<configuration>
<configSections>
</sectionGroup>
</sectionGroup>
</sectionGroup>
<section name="loginRedirectByRole" type="crabit.LoginRedirectByRoleSection" allowLocation="true" allowDefinition="Everywhere" />
</configSections>
Anteriormente definimos nuestra sección, pero esta sería totalmente inútil sin el Metodo que le da vida. En nuestro caso el metodo loginRedirectByRole, este metodo lo definiremos luego del </configSections> último que cerramos:
<loginRedirectByRole>
<roleRedirects>
<add role="Administrador" url="~/Admin/Default.aspx" />
<add role="User" url="~/User/Default.aspx" />
</roleRedirects>
</loginRedirectByRole>
Como vemos, dentro de nuestro metodo LoginRedirectByRole tenemos el elemento add role. Este elemento será el que posteriormente le indicará a la aplicación hacia donde irá el usuario cuando realice un login correcto. Así que, veamos un poco esta configuración:
add role="Administrador" corresponde al nombre del Role que tenemos definidio, pueden existir tantos elementos add role como tengamos definidos en nuestra aplicación.
El elemento URL indica la ruta o página a la que será dirigido un usuario una vez logueado y dentro de la aplicación. Como vemos estamos utilizando el ~ para indicar que es una ruta relativa.
Con esto hemos terminado la configuración de nuestro web.config, ahora veamos a fondo el código que se encargará de leer estos elementos y de utilziarlos:
Para nuestro ejemplo, crearemos una nueva clase denominada LoginRedirectByRoleSection, recordemos que esta clase es la que llamamos en el elemento TYPE definido en la sección de nuestro web.config.
Una vez creada la clase, definiremos algunas propiedades, pero antes de ello le indicaremos a nuestra clase que debe heredar de configurationSection, esto para poder obtener los elementos del web.config.
Inherits ConfigurationSection
Ahora nuestra primer propiedad
<ConfigurationProperty("roleRedirects")> _
Public Property RoleRedirects() As RoleRedirectCollection
Get
Return DirectCast(Me("roleRedirects"), RoleRedirectCollection)
End Get
Set(ByVal value As RoleRedirectCollection)
Me("roleRedirects") = value
End Set
End Property
End Class
Esta propiedad será la encargada de obtener todos los roles que definimos en la metodo personalizado de nuestro web.config
Nuestro segundo paso será crear una segunda clase (en la misma clase LoginRedirectByRoleSection) a esta clase la llamaremos RoleRedirectCollection y la heredaremos de ConfigurationElementCollection y definiremos lo siguiente
Public Class RoleRedirectCollection
Inherits ConfigurationElementCollection
Default Public ReadOnly Property Item(ByVal index As Integer) As RoleRedirect
Get
Return DirectCast(BaseGet(index), RoleRedirect)
End Get
End Property
Default Public ReadOnly Property Item(ByVal key As Object) As RoleRedirect
Get
Return DirectCast(BaseGet(key), RoleRedirect)
End Get
End Property
Protected Overrides Function CreateNewElement() As ConfigurationElement
Return New RoleRedirect()
End Function
Protected Overrides Function GetElementKey(ByVal element As ConfigurationElement) As Object
Return DirectCast(element, RoleRedirect).Role
End Function
End Class
Nuevamente crearemos otra clase esta vez llamada RoleRedirect y en este caso la heredaremos de ConfigurationElement. Nuestra nueva clase debería lucir así:
Public Class RoleRedirect
Inherits ConfigurationElement
<ConfigurationProperty("role", IsRequired:=True)> _
Public Property Role() As String
Get
Return DirectCast(Me("role"), String)
End Get
Set(ByVal value As String)
Me("role") = value
End Set
End Property
<ConfigurationProperty("url", IsRequired:=True)> _
Public Property Url() As String
Get
Return DirectCast(Me("url"), String)
End Get
Set(ByVal value As String)
Me("url") = value
End Set
End Property
End Class
Una vez que nuestra clase madre esta lista, lo unico que nos queda es un poc de codigo en la pagina de login de nuestro sistema (por supuesto, asumo que estan utilizando los controles de login que por defecto tiene asp.net).
Acá definiremos nuestros dos últimos metodos
Protected Sub ctllogin_LoggedIn(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctllogin.LoggedIn
RedirectLogin(ctllogin.UserName)
End Sub
El procedimiento loggeding es parte del control login de asp.net y se desencadena en el momento en que el usuario hace loguin correctametne en nuestra aplicación
Este evento desencadenará el siguiente procedimiento para redireccionar.
Private Sub RedirectLogin(ByVal username As String)
Dim roleRedirectSection As crabit.LoginRedirectByRoleSection = DirectCast(ConfigurationManager.GetSection("loginRedirectByRole"), crabit.LoginRedirectByRoleSection)
For Each roleRedirect As crabit.RoleRedirect In roleRedirectSection.RoleRedirects
If Roles.IsUserInRole(username, roleRedirect.Role) Then
Response.Redirect(roleRedirect.Url)
End If
Next
End Sub
Con esto, nuestra aplicación debería ser capaz de redireccionar sin problemas y manejar los roles. Además, tambien recordar que nuestro ejemplo se basa en la utilización del esquema de bases de datos que por defecto nos proporcionada asp.net.