Crear una aplicación de formularios Web Forms de ASP.NET con la autenticación en dos fases de SMS (C#)

de Erik Reitan

Descargar aplicación de ASP.NET Web Forms con autenticación en dos fases de correo electrónico y SMS

En este tutorial se muestra cómo compilar una aplicación de ASP.NET Web Forms MVC 5 con autenticación en dos fases. Este tutorial se diseñó para complementar el tutorial titulado Crear una aplicación segura ASP.NET Web Forms con registro de usuario, confirmación de correo electrónico y restablecimiento de contraseña. Además, este tutorial se basa en el tutorial de MVC de Rick Anderson.

Introducción

Este tutorial le guía por los pasos necesarios para crear una aplicación de ASP.NET Web Forms que admita autenticación en dos fases mediante Visual Studio. La autenticación en dos fases es un paso de autenticación de usuario adicional. Este paso adicional genera un número de identificación personal (PIN) único durante el inicio de sesión. El PIN se envía normalmente al usuario como correo electrónico o mensaje SMS. A continuación, el usuario de la aplicación escribe el PIN como medida de autenticación adicional al iniciar sesión.

Tareas e información del tutorial:

Crear una aplicación de ASP.NET Web Forms

Empiece por instalar y ejecutar Visual Studio Express 2013 para Web o Visual Studio 2013. Instale también Visual Studio 2013 Update 3 o superior. Además, deberá crear una cuenta de Twilio, como se explica a continuación.

Nota:

Advertencia: debe instalar Visual Studio 2013 Update 3 o posterior para completar este tutorial.

  1. Cree un nuevo proyecto (Archivo ->Nuevo proyecto) y seleccione la plantilla Aplicación web de ASP.NET y la versión 4.5.2 de .NET Framework en el cuadro de diálogo Nuevo proyecto.
  2. En el cuadro de diálogo Nuevo proyecto de ASP.NET, seleccione la plantilla Web Forms. Deje la autenticación predeterminada como Cuentas de usuario individuales. A continuación, haga clic en Aceptar para crear el nuevo proyecto.
    Screenshot of the New A S P dot Net Project dialog box showing the Web Forms icon highlighted in blue.
  3. Habilite la capa de sockets seguros (SSL) para el proyecto. Siga los pasos disponibles en la sección Habilitar SSL para el proyecto de la serie de tutoriales de Introducción a Web Forms.
  4. En Visual Studio, abra la Consola del administrador de paquetes (Herramientas ->Administrador de paquetes NuGet ->Consola del administrador de paquetes), y escriba el siguiente comando:
    Install-Package Twilio

Configurar SMS y autenticación en dos fases

En este tutorial se usa Twilio, pero puede usar cualquier proveedor de SMS.

  1. Cree una cuenta de Twilio.

  2. En la pestaña Panel de la cuenta de Twilio, copie el SID de cuenta y el token de autenticación. Los agregará a la aplicación más adelante.

  3. En la pestaña Números, copie también su número de teléfono de Twilio.

  4. Haga que el SID de cuenta de Twilio, el token de autenticación y el número de teléfono estén disponibles para la aplicación. Para simplificar, almacenaremos estos valores en el archivo Web.config. Al implementar en Azure puede almacenar los valores de forma segura en la sección de appSettings en la pestaña Configurar del sitio web. Además, al agregar el número de teléfono, use solo números.
    Tenga en cuenta que también puede agregar credenciales de SendGrid. SendGrid es un servicio de notificación por correo electrónico. Para obtener más información sobre cómo habilitar SendGrid, consulte la sección "Enlace de SendGrid" del tutorial titulado Crear una aplicación segura de ASP.NET Web Forms con registro de usuario, confirmación de correo electrónico y restablecimiento de contraseña.

    </connectionStrings>
      <appSettings>
        <!-- SendGrid Credentials-->    
        <add key="emailServiceUserName" value="[EmailServiceAccountUserName]" />
        <add key="emailServicePassword" value="[EmailServiceAccountPassword]" />
        <!-- Twilio Credentials-->
        <add key="SMSSID" value="[SMSServiceAccountSID]" />
        <add key="SMSAuthToken" value="[SMSServiceAuthorizationToken]" />
        <add key="SMSPhoneNumber" value="+[SMSPhoneNumber]" />    
      </appSettings>
      <system.web>
    

    Advertencia

    Seguridad: nunca almacene datos confidenciales en el código fuente. En este ejemplo, la cuenta y las credenciales se almacenan en la sección appSettings del archivo Web.config. En Azure, puede almacenar estos valores de forma segura en la pestaña Configurar de Azure Portal. Para obtener información relacionada, consulte el tema de Rick Anderson titulado Procedimientos recomendados para implementar contraseñas y otros datos confidenciales en ASP.NET y Azure.

  5. Configure la clase SmsService en el archivo App_Start\IdentityConfig.cs realizando los siguientes cambios resaltados en amarillo:

    public class SmsService : IIdentityMessageService
    {
        public Task SendAsync(IdentityMessage message)
        {
            var Twilio = new TwilioRestClient(
               ConfigurationManager.AppSettings["SMSSID"],
               ConfigurationManager.AppSettings["SMSAuthToken"]
            );
            var result = Twilio.SendMessage(
                ConfigurationManager.AppSettings["SMSPhoneNumber"],
               message.Destination, message.Body);
    
            // Status is one of Queued, Sending, Sent, Failed or null if the number is not valid
            Trace.TraceInformation(result.Status);
    
            // Twilio doesn't currently have an async API, so return success.
            return Task.FromResult(0);
        }
    }
    
  6. Agregue las instrucciones using siguientes al principio del archivo IdentityConfig.cs:

    using Twilio;
    using System.Net;
    using System.Configuration;
    using System.Diagnostics;
    
  7. Actualice el archivo Account/Manage.aspx quitando las líneas resaltadas en amarillo:

    <%@ Page Title="Manage Account" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Manage.aspx.cs" Inherits="WebFormsTwoFactor.Account.Manage" %>
    
    <%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %>
    
    <asp:Content ContentPlaceHolderID="MainContent" runat="server">
        <h2><%: Title %>.</h2>
    
        <div>
            <asp:PlaceHolder runat="server" ID="successMessage" Visible="false" ViewStateMode="Disabled">
                <p class="text-success"><%: SuccessMessage %></p>
            </asp:PlaceHolder>
        </div>
    
        <div class="row">
            <div class="col-md-12">
                <div class="form-horizontal">
                    <h4>Change your account settings</h4>
                    <hr />
                    <dl class="dl-horizontal">
                        <dt>Password:</dt>
                        <dd>
                            <asp:HyperLink NavigateUrl="/Account/ManagePassword" Text="[Change]" Visible="false" ID="ChangePassword" runat="server" />
                            <asp:HyperLink NavigateUrl="/Account/ManagePassword" Text="[Create]" Visible="false" ID="CreatePassword" runat="server" />
                        </dd>
                        <dt>External Logins:</dt>
                        <dd><%: LoginsCount %>
                            <asp:HyperLink NavigateUrl="/Account/ManageLogins" Text="[Manage]" runat="server" />
    
                        </dd>
                        <%--
                            Phone Numbers can used as a second factor of verification in a two-factor authentication system.
                            See <a href="https://go.microsoft.com/fwlink/?LinkId=313242">this article</a>
                            for details on setting up this ASP.NET application to support two-factor authentication using SMS.
                            Uncomment the following block after you have set up two-factor authentication
                        --%>
    
                        <dt>Phone Number:</dt>
                        <%--
                        <% if (HasPhoneNumber)
                           { %>
                        <dd>
                            <asp:HyperLink NavigateUrl="/Account/AddPhoneNumber" runat="server" Text="[Add]" />
                        </dd>
                        <% }
                           else
                           { %>
                        <dd>
                            <asp:Label Text="" ID="PhoneNumber" runat="server" />
                            <asp:HyperLink NavigateUrl="/Account/AddPhoneNumber" runat="server" Text="[Change]" /> &nbsp;|&nbsp;
                            <asp:LinkButton Text="[Remove]" OnClick="RemovePhone_Click" runat="server" />
                        </dd>
                        <% } %>
                        --%>
    
                        <dt>Two-Factor Authentication:</dt>
                        <dd>
                            <p>
                                There are no two-factor authentication providers configured. See <a href="https://go.microsoft.com/fwlink/?LinkId=313242">this article</a>
                                for details on setting up this ASP.NET application to support two-factor authentication.
                            </p>
                            <% if (TwoFactorEnabled)
                              { %> 
                            <%--
                            Enabled
                            <asp:LinkButton Text="[Disable]" runat="server" CommandArgument="false" OnClick="TwoFactorDisable_Click" />
                            --%>
                            <% }
                              else
                              { %> 
                            <%--
                            Disabled
                            <asp:LinkButton Text="[Enable]" CommandArgument="true" OnClick="TwoFactorEnable_Click" runat="server" />
                            --%>
                            <% } %>
                        </dd>
                    </dl>
                </div>
            </div>
        </div>
    </asp:Content>
    
  8. En el controlador Page_Load del código subyacente Manage.aspx.cs, quite la marca de comentario de la línea de código resaltada en amarillo para que aparezca de la siguiente manera:

    protected void Page_Load()
    {
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
    
        HasPhoneNumber = String.IsNullOrEmpty(manager.GetPhoneNumber(User.Identity.GetUserId()));
    
        // Enable this after setting up two-factor authentientication
        PhoneNumber.Text = manager.GetPhoneNumber(User.Identity.GetUserId()) ?? String.Empty;
    
        TwoFactorEnabled = manager.GetTwoFactorEnabled(User.Identity.GetUserId());
    
        LoginsCount = manager.GetLogins(User.Identity.GetUserId()).Count;
    
        var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
    
        if (!IsPostBack)
        {
            // Determine the sections to render
            if (HasPassword(manager))
            {
                ChangePassword.Visible = true;
            }
            else
            {
                CreatePassword.Visible = true;
                ChangePassword.Visible = false;
            }
    
            // Render success message
            var message = Request.QueryString["m"];
            if (message != null)
            {
                // Strip the query string from action
                Form.Action = ResolveUrl("~/Account/Manage");
    
                SuccessMessage =
                    message == "ChangePwdSuccess" ? "Your password has been changed."
                    : message == "SetPwdSuccess" ? "Your password has been set."
                    : message == "RemoveLoginSuccess" ? "The account was removed."
                    : message == "AddPhoneNumberSuccess" ? "Phone number has been added"
                    : message == "RemovePhoneNumberSuccess" ? "Phone number was removed"
                    : String.Empty;
                successMessage.Visible = !String.IsNullOrEmpty(SuccessMessage);
            }
        }
    }
    
  9. En el código subyacente de Cuenta/TwoFactorAuthenticationSignIn.aspx.cs, actualice el controlador Page_Load agregando el código siguiente resaltado en amarillo:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            var userId = signinManager.GetVerifiedUserId<ApplicationUser, string>();
            if (userId == null)
            {
                Response.Redirect("/Account/Error", true);
            }
            var userFactors = manager.GetValidTwoFactorProviders(userId);
            Providers.DataSource = userFactors.Select(x => x).ToList();
            Providers.DataBind();
        }
    }
    

    Al cambiar el código anterior, el valor DropDownList de "Proveedores" que contiene las opciones de autenticación no se restablecerá al primer valor. Esto permitirá al usuario seleccionar correctamente todas las opciones que se van a usar al autenticarse, no solo la primera.

  10. En el Explorador de soluciones, haga clic con el botón derecho en Default.aspx y seleccione Establecer como página de inicio.

  11. Al probar la aplicación, compile primero la aplicación (Ctrl+Mayús+B) y, a continuación, ejecute la aplicación (F5) y seleccione Registro para crear una nueva cuenta de usuario o seleccione Iniciar sesión si la cuenta de usuario ya se ha registrado.

  12. Una vez que haya iniciado sesión (como usuario), haga clic en el identificador de usuario (dirección de correo electrónico) de la barra de navegación para mostrar la página Administrar cuenta (Manage.aspx).
    Screenshot of the A S P dot Net response browser window showing the User I D highlighted with a red rectangle.

  13. Haga clic en Agregar junto a Número de teléfono en la página Administrar cuenta.
    Screenshot of the Manage Account browser window showing the list of account settings and option links to change them.

  14. Agregue el número de teléfono donde (como usuario) desea recibir mensajes SMS (mensajes de texto) y haga clic en el botón Enviar.
    Screenshot of the Phone Number browser window showing the Phone Number field with the entered phone number value and the Submit button.
    En este momento, la aplicación usará las credenciales de Web.config para ponerse en contacto con Twilio. Se enviará un mensaje SMS (mensaje de texto) al teléfono asociado a la cuenta de usuario. Puede comprobar que el mensaje de Twilio se envió viendo el panel de Twilio.

  15. En unos segundos, el teléfono asociado a la cuenta de usuario recibirá un mensaje de texto que contiene el código de verificación. Escriba el código de verificación y presione Enviar.
    Screenshot of the Verify Phone Number browser window showing the Code field with the entered verification code and the Submit button.

Habilitar la autenticación en dos fases para un usuario registrado

En este momento ya ha habilitado la autenticación en dos fases para la aplicación. Para que un usuario use la autenticación en dos fases, simplemente puede cambiar su configuración mediante la interfaz de usuario.

  1. Como usuario de la aplicación, puede habilitar la autenticación en dos fases para su cuenta específica haciendo clic en el identificador de usuario (alias de correo electrónico) en la barra de navegación para mostrar la página Administrar cuenta. A continuación, haga clic en el vínculo Habilitar para habilitar la autenticación en dos fases para la cuenta.Screenshot of the Manage Account browser window showing the Enable link associated with Two-Factor Authentication highlighted in red.
  2. Cierre sesión y vuelva a iniciarla. Si ha habilitado un correo electrónico, puede seleccionar SMS o correo electrónico para la autenticación en dos fases. Si no ha habilitado un correo electrónico, consulte el tutorial titulado Crear una aplicación segura de ASP.NET Web Forms con registro de usuario, confirmación de correo electrónico y restablecimiento de contraseña.Screenshot of the Two-Factor Authentication browser window showing the Select Two-Factor Authentication Provider dropdown list.
  3. La página de autenticación en dos fases se muestra donde pueda escribir el código (desde SMS o correo electrónico).Screenshot of the Two-Factor Authentication browser window showing the Code field with the entered verification code and the Submit button.
    Al hacer clic en la casilla de comprobaciónRecordar este explorador, se le eximirá de tener que usar autenticación en dos fases para iniciar sesión al usar el dispositivo y el explorador donde ha activado la casilla. Mientras los usuarios malintencionados no puedan obtener acceso al dispositivo, habilitar la autenticación en dos fases y hacer clic en el botón Recordar este explorador le proporcionará un cómodo acceso con contraseña en un solo paso mientras conserva la protección fuerte de autenticación en dos fases para cualquier acceso desde dispositivos que no son de confianza. Puede hacerlo en cualquier dispositivo privado que use con regularidad.

Recursos adicionales