Compartir a través de


Aplicación de ASP.NET MVC 5 con autenticación en dos fases por SMS y correo electrónico

por Rick Anderson

En este tutorial se muestra cómo compilar una aplicación web ASP.NET MVC 5 con autenticación en dos fases. Debe completar el tutorial Creación de una aplicación web ASP.NET MVC 5 segura con inicio de sesión, confirmación por correo electrónico y restablecimiento de contraseña antes de continuar. Puede descargar la aplicación completada aquí. La descarga contiene asistentes de depuración que le permiten probar la confirmación por correo electrónico y SMS sin configurar un proveedor de correo electrónico o de SMS.

Este tutorial lo ha escrito Rick Anderson (Twitter: @RickAndMSFT).

Creación de una aplicación ASP.NET MVC

Empiece por instalar y ejecutar Visual Studio Express 2013 para Web o una versión posterior.

Nota:

Advertencia: Debe completar el tutorial Creación de una aplicación web ASP.NET MVC 5 segura con inicio de sesión, confirmación por correo electrónico y restablecimiento de contraseña antes de continuar. Debe instalar Visual Studio 2013 Update 3 o una versión posterior para completar este tutorial.

  1. Cree un proyecto web de ASP.NET y seleccione la plantilla MVC. Web Forms también admite ASP.NET Identity, por lo que puede seguir pasos similares en una aplicación de formularios web.
    Captura de pantalla que muestra la ventana de Nuevo Proyecto de ASP.NET. La autenticación predeterminada, Cuentas de usuario individuales, está resaltada.
  2. Deje la opción predeterminada de autenticación como Cuenta de Usuario Individual. Si quiere hospedar la aplicación en Azure, deje activada la casilla. Más adelante en el tutorial se implementará en Azure. Puede abrir una cuenta de Azure de forma gratuita.
  3. Establezca el proyecto número para usar SSL.

Configuración de SMS para la autenticación en dos fases

En este tutorial se proporcionan instrucciones para usar Twilio o ASPSMS, pero puede usar cualquier otro proveedor de SMS.

  1. Creación de una cuenta de usuario con un proveedor de SMS

    Crea una cuenta de Twilio o una cuenta de ASPSMS.

  2. Instalación de paquetes adicionales o adición de referencias de servicio

    Twilio:
    En la Consola del Administrador de paquetes, escriba el siguiente comando:
    Install-Package Twilio

    ASPSMS:
    Es necesario agregar la siguiente referencia de servicio:

    Captura de pantalla que muestra la ventana Agregar referencia de servicio. Se resaltan las barras de entrada Dirección y Espacio de nombres.

    Dirección:
    https://webservice.aspsms.com/aspsmsx2.asmx?WSDL

    Espacio de nombres:
    ASPSMSX2

  3. Averiguar las credenciales de usuario del proveedor de SMS

Se recomienda usar la opción de autenticación segura más segura. Para las aplicaciones .NET implementadas en Azure, consulte:

Azure Key Vault y .NET Aspire proporcionan la manera más segura de almacenar y recuperar secretos. Azure Key Vault es un servicio en la nube que protege las claves de cifrado y los secretos, como certificados, cadenas de conexión y contraseñas. Para .NET Aspire, consulte Comunicación segura entre las integraciones de hospedaje y cliente.

Evita la concesión de credenciales de contraseña de propietario del recurso, ya que:

  • Expone la contraseña del usuario al cliente.
  • Es un riesgo de seguridad considerable.
  • Solo se debe usar cuando no se puedan usar otros flujos de autenticación.

Cuando la aplicación se implementa en un servidor de prueba, se puede utilizar una variable de entorno para establecer la cadena de conexión en un servidor de base de datos de prueba. Las variables de entorno se almacenan generalmente en texto sin formato y sin cifrar. Si la máquina o el proceso están en peligro, las partes que no son de confianza pueden acceder a las variables de entorno. Se recomienda usar variables de entorno para almacenar una cadena de conexión de producción, ya que no es el enfoque más seguro.

Directrices para los datos de configuración:

  • Nunca almacene contraseñas u otros datos confidenciales en el código del proveedor de configuración o en archivos de configuración de texto sin formato.
  • No use secretos de producción en los entornos de desarrollo o pruebas.
  • Especifique los secretos fuera del proyecto para que no se confirmen en un repositorio de código fuente de manera accidental.

Twilio:
En la pestaña Dashboard de tu cuenta de Twilio, copia el SID de cuenta y el token de autorización.

ASPSMS:
En la configuración de la cuenta, vaya a Clave de usuario y cópiela junto con la contraseña autodefinida.

Más adelante almacenaremos estos valores en el archivo web.config dentro de las claves "SMSAccountIdentification" y "SMSAccountPassword". 4. Especificación de ID del emisor/originador

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

ASPSMS:
En el menú Desbloquear originadores, desbloquee uno o varios originadores o elija un originador alfanumérico (no es compatible con todas las redes).

Más adelante almacenaremos este valor en el archivo web.config dentro de la clave "SMSAccountFrom". 5. Transferir las credenciales del proveedor de SMS a la aplicación

Haga que las credenciales y el número de teléfono del remitente estén disponibles para la aplicación. Para simplificar, almacenaremos estos valores en el archivo web.config. Al implementar en Azure, podemos almacenar los valores de forma segura en la sección de configuración de la aplicación en la pestaña configurar del sitio web.

[!code-xml[Main](aspnet-mvc-5-app-with-sms-and-email-two-factor-authentication/samples/sample1.xml?highlight=8-10)]

> [!WARNING]
> Security - Never store sensitive data in your source code. The account and credentials are added to the code above to keep the sample simple. See [Best practices for deploying passwords and other sensitive data to ASP.NET and Azure](../../../identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure.md).
  1. Implementación de la transferencia de datos al proveedor de SMS

    Configure la clase SmsService en el archivo App_Start\IdentityConfig.cs.

    En función del proveedor de SMS usado, active la sección Twilio o ASPSMS:

    public class SmsService : IIdentityMessageService
    {
        public Task SendAsync(IdentityMessage message)
        {
            // Twilio Begin
            //var accountSid = ConfigurationManager.AppSettings["SMSAccountIdentification"];
            //var authToken = ConfigurationManager.AppSettings["SMSAccountPassword"];
            //var fromNumber = ConfigurationManager.AppSettings["SMSAccountFrom"];
    
            //TwilioClient.Init(accountSid, authToken);
    
            //MessageResource result = MessageResource.Create(
                //new PhoneNumber(message.Destination),
                //from: new PhoneNumber(fromNumber),
               //body: message.Body
            //);
    
            ////Status is one of Queued, Sending, Sent, Failed or null if the number is not valid
             //Trace.TraceInformation(result.Status.ToString());
            ////Twilio doesn't currently have an async API, so return success.
             //return Task.FromResult(0);    
            // Twilio End
    
            // ASPSMS Begin 
            // var soapSms = new MvcPWx.ASPSMSX2.ASPSMSX2SoapClient("ASPSMSX2Soap");
            // soapSms.SendSimpleTextSMS(
            //   System.Configuration.ConfigurationManager.AppSettings["SMSAccountIdentification"],
            //   System.Configuration.ConfigurationManager.AppSettings["SMSAccountPassword"],
            //   message.Destination,
            //   System.Configuration.ConfigurationManager.AppSettings["SMSAccountFrom"],
            //   message.Body);
            // soapSms.Close();
            // return Task.FromResult(0);
            // ASPSMS End
        }
    }
    
  2. Actualice la vista de Razor Views\Manage\Index.cshtml: (nota: no solo quite los comentarios en el código de salida, use el código siguiente).

    @model MvcPWy.Models.IndexViewModel
    @{
       ViewBag.Title = "Manage";
    }
    <h2>@ViewBag.Title.</h2>
    <p class="text-success">@ViewBag.StatusMessage</p>
    <div>
       <h4>Change your account settings</h4>
       <hr />
       <dl class="dl-horizontal">
          <dt>Password:</dt>
          <dd>
             [
             @if (Model.HasPassword)
             {
                @Html.ActionLink("Change your password", "ChangePassword")
             }
             else
             {
                @Html.ActionLink("Create", "SetPassword")
             }
             ]
          </dd>
          <dt>External Logins:</dt>
          <dd>
             @Model.Logins.Count [
             @Html.ActionLink("Manage", "ManageLogins") ]
          </dd>
            <dt>Phone Number:</dt>
          <dd>
             @(Model.PhoneNumber ?? "None") [
             @if (Model.PhoneNumber != null)
             {
                @Html.ActionLink("Change", "AddPhoneNumber")
                @: &nbsp;|&nbsp;
                @Html.ActionLink("Remove", "RemovePhoneNumber")
             }
             else
             {
                @Html.ActionLink("Add", "AddPhoneNumber")
             }
             ]
          </dd>
          <dt>Two-Factor Authentication:</dt> 
          <dd>
             @if (Model.TwoFactor)
             {
                using (Html.BeginForm("DisableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                {
                   @Html.AntiForgeryToken()
                   <text>Enabled
                      <input type="submit" value="Disable" class="btn btn-link" />
                   </text>
                }
             }
             else
             {
                using (Html.BeginForm("EnableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                {
                   @Html.AntiForgeryToken()
                   <text>Disabled
                      <input type="submit" value="Enable" class="btn btn-link" />
                   </text>
                }
             }
          </dd>
       </dl>
    </div>
    
  3. Compruebe que los métodos de acción EnableTwoFactorAuthentication y DisableTwoFactorAuthentication en ManageController tengan el atributo [ValidateAntiForgeryToken]:

    //
    // POST: /Manage/EnableTwoFactorAuthentication
    [HttpPost,ValidateAntiForgeryToken]
    public async Task<ActionResult> EnableTwoFactorAuthentication()
    {
        await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (user != null)
        {
            await SignInAsync(user, isPersistent: false);
        }
        return RedirectToAction("Index", "Manage");
    }
    //
    // POST: /Manage/DisableTwoFactorAuthentication
    [HttpPost, ValidateAntiForgeryToken]
    public async Task<ActionResult> DisableTwoFactorAuthentication()
    {
        await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false);
        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (user != null)
        {
            await SignInAsync(user, isPersistent: false);
        }
        return RedirectToAction("Index", "Manage");
    }
    
  4. Ejecute la aplicación e inicie sesión con la cuenta que registró anteriormente.

  5. Haga clic en su identificador de usuario, lo que activa el método de acción Index del controlador Manage.
    Captura de pantalla que muestra la página principal de la aplicación ASP.NET. Se resalta una ID de usuario de ejemplo.

  6. Haga clic en Agregar.
    Captura de pantalla que muestra la página Configuración de la cuenta de la aplicación ASP.NET. Se ha resaltado la sección Ninguno agregado junto al número de teléfono.

  7. El método de acción AddPhoneNumber muestra un cuadro de diálogo para escribir un número de teléfono que puede recibir mensajes SMS.

    // GET: /Account/AddPhoneNumber
    public ActionResult AddPhoneNumber()
    {
       return View();
    }
    

    Captura de pantalla que muestra la página Agregar número de teléfono de la aplicación ASP.NET. Se rellena un número de teléfono de muestra con un botón Enviar código de verificación debajo.

  8. En unos segundos recibirá un mensaje de texto con el código de verificación. Introdúzcalo y presione Enviar.
    Captura de pantalla de la página Agregar número de teléfono de la aplicación ASP.NET, que muestra una barra de entrada con un código de verificación de muestra y un botón Enviar debajo.

  9. La vista Administrar muestra que se ha agregado tu número de teléfono.

Habilitación de la autenticación en dos fases

En la aplicación generada por la plantilla, debe usar la interfaz de usuario para habilitar la autenticación en dos fases (2FA). Para habilitar 2FA, haga clic en el identificador de usuario (alias de correo electrónico) en la barra de navegación.

Captura de pantalla que muestra la página principal de la aplicación ASP punto NET. Se resalta un ID de usuario de muestra.

Haga clic en habilitar 2FA.

Captura de pantalla que muestra la página Configuración de la cuenta de la aplicación ASP.NET. Autenticación de dos factores: Se ha resaltado la sección Deshabilitada con el vínculo Habilitar.

Cierre sesión y vuelva a iniciar sesión. Si ha habilitado el correo electrónico (consulte el tutorial anterior), puede seleccionar el SMS o el correo electrónico para 2FA.

Captura de pantalla que muestra la página Enviar código de verificación de la aplicación ASP.NET. Se selecciona un menú desplegable que muestra el código de teléfono y el código de correo electrónico.

La página Verificar código aparece, donde puede introducir el código (desde SMS o correo electrónico).

Captura de pantalla que muestra la página de verificación de la aplicación ASP.NET para 2 FA. Debajo de un código de muestra, se resalta una casilla de verificación con Recordar este navegador.

Al hacer clic en la casilla Recordar este explorador, se le eximirá de tener que usar 2FA para iniciar sesión al usar el dispositivo y el explorador donde ha activado la casilla. Siempre que los usuarios malintencionados no puedan obtener acceso al dispositivo, habilitar 2FA y hacer clic en el botón Recordar este explorador le proporcionará un cómodo acceso con contraseña mediante un solo paso mientras conserva la protección segura de 2FA para todo el acceso desde dispositivos que no son de confianza. Puede hacerlo en cualquier dispositivo privado que use con regularidad.

En este tutorial se proporciona una introducción rápida a la habilitación de 2FA en una nueva aplicación ASP.NET MVC. Mi tutorial Autenticación en dos fases mediante SMS y correo electrónico con ASP.NET Identity profundiza en el código subyacente del ejemplo.

Recursos adicionales