Seguridad de directorios en ASP.NET

6. March 2011 08:43 by Oscar.SS in Desarrollo Web  //  Tags: ,   //   Comments (10)

Practicamente en la totalidad de nuestras aplicaciones web debemos implementar la seguridad de usuarios para determininar cuales de estos tienen permisos a determinados recursos. Cuando la seguridad sea muy complicada, con multitud de niveles y sobre multitud de recursos, recuriremos a la seguridad basada en perfiles o roles almacenados en una base de datos.

Sin embargo, para contextos de seguridad mucho más simples, podemos usar la seguridad basada en establecer ciertos directorios o elementos como privados y definir unos pocos permisos en el web.config. Por ejemplo, un blog como este, en el que todas las páginas son públicas a todos los usuarios, excepto las encargadas de administrar y editar los artículos que solo serán accesibles al administrador del blog.

En casos tan sencillos como este, basaremos la seguridad mediante formularios, directorios (o elementos) privados, y la definición de permisos de usuarios en el web.config.

Supongamos que estamos desarrollando una aplicación web en el que todas sus páginas serán públicas. El contenido de estas páginas es dinámico y se edita por medio de un back office al que solo podrán acceder los administradores del sitio web. Veamos como hacerlo.

 

Definir directorios privados

En primer lugar, definimos en el web.config que directorios o elementos serán privados y cuales serán públicos. Cuando hablamos de directorios, nos referimos naturalmente a una carpeta (y todo su contenido) de nuestro proyecto. Y cuando hablamos de elementos, nos referimos por ejemplo, a ciertas páginas.

 

 

Mediante la sección <location> del web.config establecemos el directorio BackOffice como privado a todos los usuarios no autentificados.

 

<configuration>
    
<system.web>
        
<!--...-->
    
</system.web>
    
<!--Marcamos el directorio BackOffice como privado-->
    
<location path="BackOffice">
        
<system.web>
            
<authorization>
                
<deny users="?"/>
            
</authorization>
        
</system.web>
    
</location>
    
<!--...............................................-->
</configuration> 

 

Sobre la sección <location> debemos tener hacer varios apuntes:

1- Esta sección se encuentra fuera del elemento <system.web> aunque en su interior tiene una sección hija con el mismo nombre.

2- Podemos tener tantas secciones <location> como necesitemos.

3- El atributo path="" de nuestro ejemplo apunta a un directorio, pero perfectamente prodía apuntar a una sola página path="BackOffice/AdmNoticias.aspx".

4- Mediante la sección <deny users="?" /> denagamos el acceso a todos los usuarios anónimos, es decir, no autentificados. Pero también existe otra posibilidad <allow users="*" /> que da acceso a todos los usuarios ya estén autentificados o no. Con la combinación de ambos elementos estableceremos la privacidad o publicidad de nuestros recursos.

 

Autentificacion mediante formularios

Una vez establecidos, en nuestro sitio web, que recursos serán públicos y cuales privados, definimos en el web.config que la autentificación se realizará mediante formulario.

 

<configuration>
    
<system.web>
        
<!--Establecemos la configuracion de atentificacion-->
        
<authentication mode="Forms">
            
<forms loginUrl="Login.aspx">
                
<credentials passwordFormat="SHA1">
                    
<user name="administrador1" password="C46D4FJ43L6KJ424355403CCE60B85421E5E6FB62"/>
                    <
user name="administrador2" password="56J35K6J353KLL56P635KJ33L6KJ424356980MRMG"/>
                </
credentials>
            
</forms>
        
</authentication>
        
<!--...............................................-->
    
</system.web>
</configuration> 

 

En primer lugar definimos el atributo mode="Forms" indicando que la autentificación se realizará mediante formulario. En el atributo loginUrl="" indicamos la ruta en nuestro proyecto donde se encontrará el formulario de login donde los usuarios tendrán que autentificarse. Será ASP.NET quién se encarge de redirigir automaticamente a los usuarios a este formulario cuando se intente un acceso a un recurso protegido.

 

 

Mediante la sección de credenciales definimos que estás estarán codificadas mediante el algoritmo SHA1. Tan solo es una forma de proteger las contraseñas de los usuarios para que no estén estricas literalmente en el web.config o para evitar su visibilidad si la solicitud es "leida" por usuarios maliciosos.

A continuación mediante la sección <user> definimos las credenciales de los usuarios (nombre y contraseña) que tendrán acceso a los recursos privados. Ahora veremos como generar estos valores hash de codificación.

 

Generar valores hash

Para generar los valores hash de las contraseñas hacemos lo siguiente.

string claveHash System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("contraseñaUsuario""SHA1");

Al ejecutar este código, el valor de la variable claveHash contendrá la codificación SHA1 de la contraseña del usuario. Solo tendremos que copiarla y pegarla en la sección correspondiente del web.config. Naturalmente este proceso de copiar y pegar a mano en el web.config las contraseñas codificadas es poco ortodoxo, pero como ya comentamos anteriormente, estamos hablando de un contexto de seguridad donde tenemos muy pocos usuarios con credenciales. Si tuvieramos 100 usuarios con distintos roles, sería inmantenible realizarlo por este sistema en lugar de almacenarlos en una base de datos.

 

Validación de usuarios

Cuando los usuarios introducen en el formulario anterior sus credenciales (nombre y contraseña)...¿como los validamos contra las credenciales definidas en el web.config?

 

    protected void ibLogin_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        
if (System.Web.Security.FormsAuthentication.Authenticate(txUsuario.Value, txPassword.Value))
            System.Web.Security.FormsAuthentication.RedirectFromLoginPage(txUsuario.Value, 
false);
        else
            
spError.InnerText "Usted no está autorizado para entrar a este sitio";
    
}

 

En primer lugar, comprobamos si las credenciales escritas en el formulario por el usuario corresponden con algunas de las que hemos defnimos anteriormente en el web.config. En caso afirmativo, redirigimos al usuario al recurso al que estaba intentando acceder.

De esta redirección se ocupa por nosotros ASP.NET. Funciona de la siguiente manera. Cuando nosotros intentamos acceder a un recurso protegido mediante una petición,

- GET //www.misitio.com/BackOffice/AdmNoticias.aspx

ASP.NET nos redirige automaticamente al recurso que hemos establecido como login en el web.config de la siguiente forma.

- GET //www.misitio.com/Login.aspx?ReturnUrl=/BackOffice/AdmNoticias.aspx

Como se puede apreciar en la url anterior, ASP.NET se encargará, mediante el parámetro de QueryString ReturnUrl una vez verificadas las credenciales del usuario, de enviarnos al recurso al que intentabamos acceder.

Comments (10) -

Jorge
Jorge
1/1/2012 11:23:09 PM #

Hola... Muy Buen tutorial Gracias. Yo hago todo lo que esta alli..Pero tenog un problema..
Tengo varios Tipos de Usuarios en mi Base de Datos, con estos perfiles:
SAMM-ADMIN (ADMINISTRADOR)
samm-Analista (Acceso a dos paginas)
Samm-operador (Acceso a una pagina)

Como puedo denegar "las paginas" a esos usuarios mediante el perfil una vez se logueen que no tengan acceso? usando el ejemplo que has colocado aqui?
Saludos.

Óscar.SS
Óscar.SS
1/2/2012 12:52:05 AM #

Hola Jorge:

La gestión de roles siempre tiene algo más de trabajo. Existen varias formas de trabajar con ellos en función de los requisitos de la aplicación, complejidad y también del gusto del programador. Resumiendo mucho, podemos tomar dos caminos distintos, desarrollar desde cero nuestra propia gestión por ejemplo con un módulo (msdn.microsoft.com/es-es/library/bb972205.aspx) o utilizar el sistema de menbresía de ASP.NET (geeks.ms/.../membres-a-de-asp-net-2-0-i.aspx)

Un saludo y gracias por tu comentario.


Angela
Angela
6/6/2012 6:05:24 PM #

Hola, muchas gracias por la explicación. Me gustaría saber cómo hacer el proceso a la inversa, es decir negar el acceso a todos los usuarios que no estén autenticados. Yo encontré una forma de hacerlo, pero también me bloquea la página de login, lo cual no es correcto pues la única página que podría ser visible de mi aplicación web es LogOn.aspx ¿Qué podría hacer? Si sirve de algo pongo a continuación parte del web.config:

<system.web>
      .
      .
      .
    <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="20" name=".ASPXFORMSAUTH" />
    </authentication>

    <authorization>
      <deny users="?" />
    </authorization>
      .
      .
      .
</system.web>
<location path="LogOn.aspx">
    <system.web>
      <authorization>
        <allow users ="?" />
      </authorization>
    </system.web>
  </location>

Óscar.SS
Óscar.SS
6/7/2012 8:23:35 PM #

Hola Angela:

Si quieres que un recurso se público tienes que especificarlo. Si no me equivoco (no puedo probarlo ahora) en tu caso sería así:

<!--Marcamos el directorio raíz como privado-->
<location path="/">
    <system.web>
      <authorization>
        <allow users ="?" />
      </authorization>
    </system.web>
  </location>
<!--Marcamos la página de LogOn como pública-->
<location path="LogOn.aspx">
    <system.web>
      <authorization>
        <allow users ="*" />
      </authorization>
    </system.web>
  </location>

Prueba con esto y me cuentas si funciona.

Un saludo

Lord Belial
Lord Belial
10/30/2012 2:55:07 AM #

Excelente tutorial, muchas gracias.

Oscar.SS
Oscar.SS
10/30/2012 9:08:51 AM #

Gracias a ti por leerlo Lord Belial Smile

emanuel
emanuel
5/14/2013 9:06:05 PM #

Hola, el tutorial esta muy bueno, me sirvio de mucho!!

Me gustaria saber si hay forma de avisarle al web.config que me autentique y me de acceso a las paginas
pero con JQuery..

FormsAuthentication.RedirectFromLoginPage(txUsuario.Value, false) pero con JQuery..

Saludos!!

Oscar.SS
Oscar.SS
5/15/2013 9:29:56 AM #

Hola Emanuel,

No se puede y no se debe hacer lo que comentas. Ten en cuenta que cualquier usuario puede modificar tu código cliente con las developer toolbars o modificar las peticiones con herramientas como Fiddler.

Un saludo

Guillermo
Guillermo
10/31/2013 9:52:22 PM #

Hola, muchas gracias por tu tutorial me funciona bien, sólo qué: una vez validadas las credenciales cuanto dura la sesión abierta, es decir si el admin cierra y abre el navegador, sigue logueado?.

Espero haberme podido explicar.

Saludos!

Oscar.SS
Oscar.SS
11/2/2013 10:08:29 PM #

Hola Guillermo,

Pues ahora mismo de memoria no recuerdo si este sistema guarda cookies en el cliente. Apostaría que no!!. De todas formas lo mejor es que lo pruebes por ti mismo Wink

Un saludo

Recent Comments

Comment RSS

Month List