Implementar la autenticación basada en formularios en una ASP.NET mediante C#.NET

En este artículo se muestra cómo implementar la autenticación basada en formularios mediante una base de datos para almacenar los usuarios. Hace referencia a los siguientes espacios de nombres .NET Framework biblioteca de clases de Microsoft:

  • System.Data.SqlClient
  • System.Web.Security

Versión del producto original:   ASP.NET
Número KB original:   301240

Requisitos

En la siguiente lista se describen los paquetes de hardware, software, infraestructura de red y service pack recomendados que necesita:

  • Visual Studio .NET
  • Internet Information Services (IIS) versión 5.0 o posterior
  • SQL Server

Crear una aplicación ASP.NET mediante C# .NET

  1. Abra Visual Studio .NET.
  2. Cree una nueva ASP.NET web y especifique el nombre y la ubicación.

Configurar las opciones de seguridad en el Web.config archivo

En esta sección se muestra cómo agregar y modificar las secciones de configuración y para configurar la aplicación ASP.NET usar la autenticación basada <authentication> <authorization> en formularios.

  1. En el Explorador de soluciones, abra el archivo Web.config.

  2. Cambie el modo de autenticación a Formularios.

  3. Inserte la <Forms> etiqueta y rellene los atributos adecuados. Copie el siguiente código y, a continuación, seleccione Pegar como HTML en el menú Editar para pegar el código en la sección <authentication> del archivo:

    <authentication mode="Forms">
        <forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx"
            protection="All" path="/" timeout="30" />
    </authentication>
    
  4. Denegar el acceso al usuario anónimo en la <authorization> sección de la siguiente manera:

    <authorization>
        <deny users ="?" />
        <allow users = "*" />
    </authorization>
    

Crear una tabla de base de datos de ejemplo para almacenar los detalles de los usuarios

En esta sección se muestra cómo crear una base de datos de ejemplo para almacenar el nombre de usuario, la contraseña y el rol de los usuarios. Necesita la columna de roles si desea almacenar roles de usuario en la base de datos e implementar la seguridad basada en roles.

  1. En el menú Inicio, seleccione Ejecutar y, a continuación, escriba bloc de notas para abrir el Bloc de notas.

  2. Resalte el siguiente SQL script, haga clic con el botón secundario en el código y, a continuación, seleccione Copiar. En el Bloc de notas, seleccione Pegar en el menú Editar para pegar el código siguiente:

    if exists (select * from sysobjects where id =
    object_id(N'[dbo].[Users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
        drop table [dbo].[Users]
    GO
    CREATE TABLE [dbo].[Users] ([uname] [varchar] (15) NOT NULL,
        [Pwd] [varchar] (25) NOT NULL,
        [userRole] [varchar] (25) NOT NULL,
    ) ON [PRIMARY]
    GO
    ALTER TABLE [dbo].[Users] WITH NOCHECK ADD
        CONSTRAINT [PK_Users] PRIMARY KEY NONCLUSTERED
        ([uname]
        ) ON [PRIMARY]
    GO
    
    INSERT INTO Users values('user1','user1','Manager')
    INSERT INTO Users values('user2','user2','Admin')
    INSERT INTO Users values('user3','user3','User')
    GO
    
  3. Guarde el archivo como Users.sql.

  4. En el SQL Server, abra Users.sql en el Analizador de consultas. En la lista de bases de datos, seleccione pubs y ejecute el script. Esta operación crea una tabla de usuarios de ejemplo y rellena la tabla de la base de datos Pubs que se usará con esta aplicación de ejemplo.

Crear una página Logon.aspx

  1. Agregue un nuevo formulario web al proyecto denominado Logon.aspx.

  2. Abra la página Logon.aspx en el editor y cambie a la vista HTML.

  3. Copie el código siguiente y use la opción Pegar como HTML del menú Editar para insertar el código entre las <form> etiquetas:

    <h3>
        <font face="Verdana">Logon Page</font>
    </h3>
    <table>
        <tr>
            <td>Email:</td>
            <td><input id="txtUserName" type="text" runat="server"></td>
            <td><ASP:RequiredFieldValidator ControlToValidate="txtUserName"
                Display="Static" ErrorMessage="*" runat="server" 
                ID="vUserName" /></td>
        </tr>
        <tr>
            <td>Password:</td>
            <td><input id="txtUserPass" type="password" runat="server"></td>
            <td><ASP:RequiredFieldValidator ControlToValidate="txtUserPass"
            Display="Static" ErrorMessage="*" runat="server"
            ID="vUserPass" />
            </td>
        </tr>
        <tr>
            <td>Persistent Cookie:</td>
            <td><ASP:CheckBox id="chkPersistCookie" runat="server" autopostback="false" /></td>
            <td></td>
        </tr>
    </table>
    <input type="submit" Value="Logon" runat="server" ID="cmdLogin"><p></p>
    <asp:Label id="lblMsg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat="server" />
    

    Este formulario web se usa para presentar un formulario de inicio de sesión a los usuarios para que puedan proporcionar su nombre de usuario y contraseña para iniciar sesión en la aplicación.

  4. Cambie a la vista Diseño y guarde la página.

Codificar el controlador de eventos para que valide las credenciales de usuario

En esta sección se muestra el código que se coloca en la página de código subyacente (Logon.aspx.cs).

  1. Haga doble clic en Inicio de sesión para abrir Logon.aspx.cs archivo.

  2. Importe los espacios de nombres necesarios en el archivo de código subyacente:

    using System.Data.SqlClient;
    using System.Web.Security;
    
  3. Cree una ValidateUser función para validar las credenciales de usuario buscando en la base de datos. Asegúrese de cambiar la cadena Connection para que apunte a la base de datos.

    private bool ValidateUser( string userName, string passWord )
    {
        SqlConnection conn;
        SqlCommand cmd;
        string lookupPassword = null;
    
        // Check for invalid userName.
        // userName must not be null and must be between 1 and 15 characters.
        if ( ( null == userName ) || ( 0 == userName.Length ) || ( userName.Length > 15 ))
        {
            System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of userName failed." );
            return false;
        }
    
        // Check for invalid passWord.
        // passWord must not be null and must be between 1 and 25 characters.
        if ( ( null == passWord ) || ( 0 == passWord.Length ) || ( passWord.Length > 25 ))
        {
            System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of passWord failed." );
            return false;
        }
    
        try
        {
            // Consult with your SQL Server administrator for an appropriate connection
            // string to use to connect to your local SQL Server.
            conn = new SqlConnection( "server=localhost;Integrated Security=SSPI;database=pubs" );
            conn.Open();
    
            // Create SqlCommand to select pwd field from users table given supplied userName.
            cmd = new SqlCommand( "Select pwd from users where uname=@userName", conn );
            cmd.Parameters.Add( "@userName", SqlDbType.VarChar, 25 );
            cmd.Parameters["@userName"].Value = userName;
    
            // Execute command and fetch pwd field into lookupPassword string.
            lookupPassword = (string) cmd.ExecuteScalar();
    
            // Cleanup command and connection objects.
            cmd.Dispose();
            conn.Dispose();
        }
        catch ( Exception ex )
        {
            // Add error handling here for debugging.
            // This error message should not be sent back to the caller.
            System.Diagnostics.Trace.WriteLine( "[ValidateUser] Exception " + ex.Message );
        }
    
        // If no password found, return false.
        if ( null == lookupPassword )
        {
            // You could write failed login attempts here to event log for additional security.
            return false;
        }
    
        // Compare lookupPassword and input passWord, using a case-sensitive comparison.
        return ( 0 == string.Compare( lookupPassword, passWord, false ));
    }
    
  4. Puede usar uno de los dos métodos para generar la cookie de autenticación de formularios y redirigir al usuario a una página adecuada en el cmdLogin_ServerClick evento. Se proporciona código de ejemplo para ambos escenarios. Use cualquiera de ellos según su requisito.

    • Llame al método para generar automáticamente la cookie de autenticación de formularios y RedirectFromLoginPage redirigir al usuario a una página adecuada en el cmdLogin_ServerClick evento:

      private void cmdLogin_ServerClick(object sender, System.EventArgs e)
      {
          if (ValidateUser(txtUserName.Value,txtUserPass.Value))
              FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPersistCookie.Checked);
          else
              Response.Redirect("logon.aspx", true);
      }
      
    • Generar el vale de autenticación, cifrarlo, crear una cookie, agregarlo a la respuesta y redirigir al usuario. Esta operación le proporciona más control en la forma de crear la cookie. También puede incluir datos personalizados junto con el FormsAuthenticationTicket en este caso.

      private void cmdLogin_ServerClick(object sender, System.EventArgs e)
      {
          if (ValidateUser(txtUserName.Value,txtUserPass.Value))
          {
              FormsAuthenticationTicket tkt;
              string cookiestr;
              HttpCookie ck;
              tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now,
              DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data");
              cookiestr = FormsAuthentication.Encrypt(tkt);
              ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
              if (chkPersistCookie.Checked)
                  ck.Expires=tkt.Expiration;
              ck.Path = FormsAuthentication.FormsCookiePath;
              Response.Cookies.Add(ck);
      
              string strRedirect;
              strRedirect = Request["ReturnUrl"];
              if (strRedirect==null)
                  strRedirect = "default.aspx";
              Response.Redirect(strRedirect, true);
          }
          else
              Response.Redirect("logon.aspx", true);
      }
      
  5. Asegúrese de que el siguiente código se agrega al método en InitializeComponent el código que genera el Diseñador de formularios web:

    this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);
    

Crear una página Default.aspx

En esta sección se crea una página de prueba a la que se redirige a los usuarios después de autenticarse. Si los usuarios exploran esta página sin iniciar sesión primero en la aplicación, se redirigen a la página de inicio de sesión.

  1. Cambie el nombre de la página WebForm1.aspx existente como Default.aspx y ábrala en el editor.

  2. Cambie a la vista HTML y copie el siguiente código entre las <form> etiquetas:

    <input type="submit" Value="SignOut" runat="server" id="cmdSignOut">
    

    Este botón se usa para cerrar sesión en la sesión de autenticación de formularios.

  3. Cambie a la vista Diseño y guarde la página.

  4. Importe los espacios de nombres necesarios en el archivo de código subyacente:

    using System.Web.Security;
    
  5. Haga doble clic en SignOut para abrir la página de código subyacente (Default.aspx.cs) y copie el siguiente código en el controlador cmdSignOut_ServerClick de eventos:

    private void cmdSignOut_ServerClick(object sender, System.EventArgs e)
    {
        FormsAuthentication.SignOut();
        Response.Redirect("logon.aspx", true);
    }
    
  6. Asegúrese de que el siguiente código se agrega al método en InitializeComponent el código que genera el Diseñador de formularios web:

    this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);
    
  7. Guarde y compile el proyecto. Ahora puede usar la aplicación.

Notas adicionales

  • Es posible que desee almacenar contraseñas de forma segura en una base de datos. Puede usar la función de utilidad de clase denominada para cifrar las contraseñas antes de almacenarlas en la base de datos FormsAuthentication o el archivo de HashPasswordForStoringInConfigFile configuración.

  • Es posible que desee almacenar la SQL de conexión en el archivo de configuración (Web.config) para poder modificarla fácilmente si es necesario.

  • Puedes considerar agregar código para evitar que los hackers que intenten usar combinaciones diferentes de contraseñas puedan iniciar sesión. Por ejemplo, puede incluir lógica que acepte solo dos o tres intentos de inicio de sesión. Si los usuarios no pueden iniciar sesión en algunos intentos, es posible que desee establecer una marca en la base de datos para no permitirles iniciar sesión hasta que los usuarios vuelvan a habilitar sus cuentas visitando otra página o llamando a la línea de soporte técnico. Además, debe agregar el control de errores adecuado siempre que sea necesario.

  • Dado que el usuario se identifica en función de la cookie de autenticación, es posible que desee usar la capa de sockets seguros (SSL) en esta aplicación para que nadie pueda engañar a la cookie de autenticación ni a ninguna otra información valiosa que se esté transmitiendo.

  • La autenticación basada en formularios requiere que el cliente acepte o habilite cookies en su explorador.

  • El parámetro timeout de la sección de configuración controla el intervalo al que se regenera la <authentication> cookie de autenticación. Puede elegir un valor que proporciona un mejor rendimiento y seguridad.

  • Algunos servidores proxy intermediarios y cachés en Internet pueden almacenar en caché las respuestas del servidor web que contienen encabezados, que luego se Set-Cookie devuelven a un usuario diferente. Dado que la autenticación basada en formularios usa una cookie para autenticar a los usuarios, este comportamiento puede provocar que los usuarios suplanten accidentalmente (o intencionadamente) a otro usuario al recibir una cookie de un proxy o caché intermediario que no estaba pensado originalmente para ellos.

Referencias