Compartir vía


Crear una aplicación de ASP.NET MVC 5 con el inicio de sesión OAuth2 de Facebook, Twitter, LinkedIn y Google (C#)

Por Rick Anderson

En este tutorial se muestra cómo crear una aplicación web de ASP.NET MVC 5 que permita a los usuarios iniciar sesión mediante OAuth 2.0 con credenciales de un proveedor de autenticación externo, como Facebook, Twitter, LinkedIn, Microsoft o Google. Para simplificar, este tutorial se centra en el uso de credenciales de Facebook y Google.

La habilitación de estas credenciales en los sitios web proporciona una ventaja significativa porque millones de usuarios ya tienen cuentas con estos proveedores externos. Estos usuarios pueden estar más inclinados a registrarse en el sitio si no tienen que crear y recordar un nuevo conjunto de credenciales.

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

En el tutorial también se muestra cómo agregar datos de perfil del usuario y cómo usar la API de pertenencia para agregar roles. Este tutorial lo ha escrito Rick Anderson (puede seguirlo en Twitter: @RickAndMSFT).

Introducción

Empiece por instalar y ejecutar Visual Studio Express 2013 para Web o Visual Studio 2013. Instale Visual Studio 2013 Update 3 o superior.

Nota:

Debe instalar Visual Studio 2013 Update 3 o superior para usar Google OAuth 2 y para depurar localmente sin recibir advertencias SSL.

Haga clic en Nuevo proyecto en la página Inicio, o bien puede usar el menú y seleccionar Archivo y, a continuación, Nuevo proyecto.

Screenshot that shows the Visual Studio Start page.

Crear la primera aplicación

Haga clic en Nuevo proyecto y, a continuación, seleccione Visual C# a la izquierda, luego Web y, por último, Aplicación web de ASP.NET. Asigne al proyecto el nombre "MvcAuth" y haga clic en Aceptar.

Screenshot that shows the Visual Studio New Project menu page. M v c Auth is entered on the Name text field.

En el cuadro de diálogo Nuevo proyecto de ASP.NET, haga clic en MVC. Si la autenticación no es Cuentas de usuarios individuales, haga clic en el botón Cambiar autenticación y seleccione Cuentas de usuarios individuales. Si se selecciona Host en la nube, la aplicación será muy fácil de hospedar en Azure.

Screenshot that shows the New A S P dot NET Project dialog box. The Change Authentication button and Host in the cloud checkbox are highlighted.

Si ha seleccionado Host en la nube, complete el cuadro de diálogo de configuración.

Screenshot that shows the Configure Microsoft Azure Website dialog box. A sample database password is entered.

Usar NuGet para actualizar el middleware de OWIN más reciente

Use el administrador de paquetes NuGet para actualizar el middleware de OWIN. Seleccione Actualizaciones en el menú de la izquierda. Puede hacer clic en el botón Actualizar todo o buscar solo los paquetes de OWIN (que se muestran en la siguiente imagen):

Screenshot that shows the Manage Nu GET Packages dialog box. The Updates bar and Update All button are highlighted.

En la siguiente imagen solo se muestran los paquetes de OWIN:

Screenshot that shows the Manage Nu GET Packages dialog box. The Updates bar and Search bar with OWN entered in it are highlighted.

En la Consola del Administrador de paquetes (PMC), puede escribir el comando Update-Package, que actualizará todos los paquetes.

Presione F5 o Ctrl+F5 para ejecutar la aplicación. En la imagen siguiente, el número de puerto es el 1234. Cuando ejecute la aplicación, verá un número de puerto diferente.

Según el tamaño de la ventana del explorador, es posible que tenga que hacer clic en el icono de navegación para ver los vínculos Inicio, Acerca de, Contacto, Registro e Iniciar sesión.

Screenshot that shows the My A S P dot NET Home page. The Navigation icon is highlighted.
Screenshot that shows the My A S P dot NET Home page. The Navigation icon is highlighted and selected, showing a dropdown menu with navigation links.

Configurar SSL en el proyecto

Para conectarse a proveedores de autenticación como Google y Facebook, deberá configurar IIS-Express para usar SSL. Es importante seguir usando SSL después del inicio de sesión y no volver a HTTP: la cookie de inicio de sesión es tan secreta como el nombre de usuario y la contraseña y, si no se usa SSL, la estará enviando en texto no cifrado a través de la conexión. Además, ya se ha tomado su tiempo en realizar el protocolo de enlace y en proteger el canal (que es en gran medida lo que hace que HTTPS sea más lento que HTTP) antes de que se ejecute la canalización de MVC, por lo que redirigir a HTTP después de haber iniciado sesión no hará que la solicitud actual o las solicitudes futuras sean mucho más rápidas.

  1. En el Explorador de soluciones, haga clic en el proyecto MvcAuth.

  2. Presione la tecla F4 para ver las propiedades del proyecto. Como alternativa, en el menú Vista puede seleccionar la ventana Propiedades.

  3. Cambie SSL habilitado a True.

    Screenshot that shows the Solution Explorer Project Properties for the M v c Auth Project. S S L Enabled True and S S L U R L are highlighted.

  4. Copie la dirección URL de SSL (que será https://localhost:44300/, a menos que haya creado otros proyectos SSL).

  5. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto MvcAuth y seleccione Propiedades.

  6. Seleccione la pestaña Web y pegue la dirección URL SSL en el cuadro Dirección URL del proyecto. Guarde el archivo (Ctrl+S). Necesitará esta dirección URL para configurar las aplicaciones de autenticación de Facebook y Google.

    Screenshot that shows the M v c Auth project's properties page. The Web tab on the left menu and the S S L U R L pasted in the Project U R L box are highlighted.

  7. Agregue el atributo RequireHttps al controlador Home para requerir que todas las solicitudes usen HTTPS. Un enfoque más seguro es agregar el filtro RequireHttps a la aplicación. Consulte la sección "Proteger la aplicación con SSL y el atributo Authorize" de mi tutorial Crear una aplicación ASP.NET MVC con autenticación y base de datos SQL e implementarla en Azure App Service. A continuación se muestra una parte del controlador HomeController.

    [RequireHttps]
    public class HomeController : Controller
    {
       public ActionResult Index()
       {
          return View();
       }
    
  8. Presione CTRL+F5 para ejecutar la aplicación. Si ha instalado el certificado en el pasado, puede omitir el resto de esta sección y pasar a Crear una aplicación de Google para OAuth 2 y conectarla al proyecto; de lo contrario, siga las instrucciones para confiar en el certificado autofirmado que IIS-Express ha generado.

    Screenshot that shows a Visual Studio dialog box prompting the user to choose whether or not to trust the I I S Express S S L certificate.

  9. Lea el cuadro de diálogo Advertencia de seguridad y después haga clic en si quiere instalar el certificado que representa a localhost.

    Screenshot that shows the Visual Studio Security Warning dialog box prompting the user to choose whether or not to install the certifcate.

  10. IE muestra la página Inicio , sin ninguna advertencia de SSL.

    Screenshot that shows the My A S P dot NET Home page with no S S L warnings.

  11. Google Chrome también acepta el certificado y mostrará contenido HTTPS sin una advertencia. Firefox usa su propio almacén de certificados, por lo que mostrará una advertencia. En el caso de nuestra aplicación, puede hacer clic de forma segura en Entiendo los riesgos.

    Screenshot that shows the My A S P dot NET app running on Firefox. An Untrusted Connection warning page is asking the user whether or not to accept the application and proceed.

Crear una aplicación de Google para OAuth 2 y conectarla al proyecto

Advertencia

Para obtener instrucciones actuales sobre OAuth de Google, consulte Configurar la autenticación de Google en ASP.NET Core.

  1. Navegue a la consola de desarrolladores de Google.

  2. Si no ha creado un proyecto antes, seleccione Credenciales en la pestaña izquierda y, a continuación, seleccione Crear.

  3. En la pestaña de la izquierda, haga clic en Credenciales.

  4. Haga clic en Crear credenciales y, a continuación, en Id. de cliente de OAuth.

    1. En el cuadro de diálogo Crear Id. de cliente, mantenga la aplicación web predeterminada del tipo de aplicación.
    2. Establezca Orígenes de JavaScript autorizados en la dirección URL de SSL que usó antes (https://localhost:44300/, a menos que haya creado otros proyectos de SSL).
    3. Establezca URI de redirección autorizado en:
      https://localhost:44300/signin-google
  5. Haga clic en el elemento de menú de la pantalla Consentimiento de OAuth y, a continuación, establezca la dirección de correo electrónico y el nombre del producto. Cuando haya completado el formulario, haga clic en Guardar.

  6. Haga clic en el elemento de menú Biblioteca, busque Google+ API, haga clic en él y presione Habilitar.

    Screenshot displaying a list of search results. The Google plus A P I search result is highlighted.

    En la imagen siguiente se muestran las API habilitadas.

    Screenshot that shows the Google Developers Console page listing enabled A P I's. A P I's show as enabled when a green ON button appears next to it.

  7. En el administrador de API de Google, visite la pestaña Credenciales para obtener el Id. de cliente. Descargue para guardar un archivo JSON con los secretos de aplicación. Copie y pegue los valores de ClientId y ClientSecret en el método UseGoogleAuthentication que se encuentra en el archivo Startup.Auth.cs de la carpeta App_Start. Los valores de ClientId y ClientSecret que se muestran a continuación son ejemplos y no funcionan.

    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    
        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });
        
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");
    
        //app.UseTwitterAuthentication(
        //   consumerKey: "",
        //   consumerSecret: "");
    
        //app.UseFacebookAuthentication(
        //   appId: "",
        //   appSecret: "");
    
        app.UseGoogleAuthentication(
             clientId: "000-000.apps.googleusercontent.com",
             clientSecret: "00000000000");
    }
    

    Advertencia

    Seguridad: nunca almacene datos confidenciales en el código fuente. La cuenta y las credenciales se agregan al código anterior para simplificar el ejemplo. Consulte Prácticas recomendadas para implementar contraseñas y otros datos confidenciales en ASP.NET y Azure App Service.

  8. Presione CTRL+F5 para compilar y ejecutar la aplicación. Haga clic en el vínculo Iniciar sesión .

    Screenshot that shows the My A S P dot NET Home page. The Navigation button and Log in link are highlighted.

  9. En Utilice otro servicio para iniciar sesión, haga clic en Google.

    Screenshot that shows the My A S P dot NET Log in page. The Use another service to log in dialog and Google button are highlighted.

    Nota:

    Si alguno de los pasos anteriores falta, obtendrá un error HTTP 401. Vuelva a comprobar los pasos. Si pierde una configuración necesaria (por ejemplo, nombre de producto), agregue el elemento que falta y guarde; la autenticación puede tardar unos minutos en funcionar.

  10. Se le redirigirá al sitio de Google, donde escribirá sus credenciales.

    Screenshot that shows a Google Accounts sign in page. Sample credentials are entered in the text fields.

  11. Una vez que haya proporcionado sus credenciales, el sistema le pedirá que le dé permisos a la aplicación web que acaba de crear:

    Screenshot that shows the Google Accounts Request for Permission page, prompting the user to either cancel or accept offline access to the web application.

  12. Haga clic en Aceptar. Después, se le redirigirá a la página de registro de la aplicación MvcAuth, donde puede registrar la cuenta de Google. Tiene la opción de cambiar el nombre de registro de correo electrónico local que usa para su cuenta de Gmail, pero suele ser más práctico mantener el mismo alias de correo electrónico predeterminado (es decir, el que usó para la autenticación). Haga clic en Registrar.

    Screenshot that shows the My A S P dot NET Register Application page. A sample Google account is entered in the email text field.

Crear la aplicación en Facebook y conectar la aplicación al proyecto

Advertencia

Para obtener instrucciones de autenticación actuales de OAuth2 de Facebook, consulte Configurar la autenticación de Facebook.

Examinar los datos de pertenencia mediante el Explorador de servidores

En el menú Vista, haga clic en el Explorador de servidores.

Screenshot that shows the Visual Studio VIEW dropdown menu, where Server Explorer is highlighted.

Expanda DefaultConnection (MvcAuth) y Tablas, haga clic con el botón derecho en AspNetUsers y, por último, haga clic en Mostrar datos de tabla.

Screenshot that shows the Service Explorer menu options. The Data Connections, Default Connection M v c Auth, and Tables tabs are expanded.

aspnetusers table data

Agregar datos de perfil a la clase User

En esta sección agregará la fecha de nacimiento y la ciudad natal a los datos del usuario durante el registro, como se muestra en la siguiente imagen.

reg with home town and Bday

Abra el archivo Models\IdentityModels.cs y agregue las propiedades fecha de nacimiento y ciudad principal:

public class ApplicationUser : IdentityUser
{
    public string HomeTown { get; set; }
    public System.DateTime? BirthDate { get; set; }
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

Abra el archivo Models\AccountViewModels.cs y establezca las propiedades de fecha de nacimiento y ciudad natal en ExternalLoginConfirmationViewModel.

public class ExternalLoginConfirmationViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    public string HomeTown { get; set; }
    public System.DateTime? BirthDate { get; set; }
}

Abra el archivo Controllers\AccountController.cs y agregue código para la fecha de nacimiento y la ciudad natal en el método de acción ExternalLoginConfirmation, como se muestra:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
    if (User.Identity.IsAuthenticated)
    {
        return RedirectToAction("Manage");
    }

    if (ModelState.IsValid)
    {
        // Get the information about the user from the external login provider
        var info = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return View("ExternalLoginFailure");
        }
        var user = new ApplicationUser() 
        {
            UserName = model.Email, Email = model.Email,
            BirthDate = model.BirthDate,
            HomeTown  = model.HomeTown
        
        };
        IdentityResult result = await UserManager.CreateAsync(user);
        if (result.Succeeded)
        {
            result = await UserManager.AddLoginAsync(user.Id, info.Login);
            if (result.Succeeded)
            {
                await SignInAsync(user, isPersistent: false);
                
                // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                // Send an email with this link
                // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                // SendEmail(user.Email, callbackUrl, "Confirm your account", "Please confirm your account by clicking this link");
                
                return RedirectToLocal(returnUrl);
            }
        }
        AddErrors(result);
    }

    ViewBag.ReturnUrl = returnUrl;
    return View(model);
}

Agregue la fecha de nacimiento y la ciudad natal al archivo Views\Account\ExternalLoginConfirmation.cshtml:

@model MvcAuth.Models.ExternalLoginConfirmationViewModel
@{
    ViewBag.Title = "Register";
}
<h2>@ViewBag.Title.</h2>
<h3>Associate your @ViewBag.LoginProvider account.</h3>

@using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()

    <h4>Association Form</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <p class="text-info">
        You've successfully authenticated with <strong>@ViewBag.LoginProvider</strong>.
            Please enter a user name for this site below and click the Register button to finish
            logging in.
    </p>
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.HomeTown, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.HomeTown, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.HomeTown)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.BirthDate, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.BirthDate, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.BirthDate)
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Register" />
        </div>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Elimine la base de datos de pertenencia para que pueda volver a registrar su cuenta de Facebook con la aplicación, y compruebe que puede agregar la nueva información de perfil de fecha de nacimiento y ciudad natal.

En el Explorador de soluciones, haga clic en el icono Mostrar todos los archivos, haga clic con el botón derecho en Add_Data\aspnet-MvcAuth-<>marcaDeFecha y haga clic en Eliminar.

Screenshot that shows the Solution Explorer page. The Show All Files icon and M v c Auth membership database are highlighted.

En el menú Herramientas, haga clic en Administrador de paquetes NuGet y luego en Consola del Administrador de paquetes (PMC). Escriba los siguientes comandos en la Consola del Administrador de paquetes.

  1. Enable-Migrations
  2. Add-Migration Init
  3. Update-Database

Ejecute la aplicación y use FaceBook y Google para iniciar sesión y registrar algunos usuarios.

Examinar los datos de pertenencia

En el menú Vista, haga clic en el Explorador de servidores.

Screenshot that shows the Visual Studio VIEW dropdown menu. The Service Explorer option is highlighted.

Haga clic con el botón derecho en AspNetUsuarios y haga clic en Mostrar datos de tabla.

Screenshot that shows the Server Explorer menu options. The A s p Net Users and the Show Table Data options are highlighted.

Aquí se muestran los campos HomeTown y BirthDate.

Screenshot that shows the A s p Net Users table data. The table data shows the I D, Home Town, Birth Date, Email, and Email Confirmed fields.

Cerrar la sesión de la aplicación e iniciar sesión con otra cuenta

Si inicia sesión en la aplicación con Facebook y, a continuación, cierra sesión e intenta volver a iniciar sesión con otra cuenta de Facebook (con el mismo explorador), se iniciará sesión inmediatamente en la cuenta de Facebook anterior que usó. Para usar otra cuenta, debe ir a Facebook y cerrar sesión en Facebook. La misma regla se aplica a cualquier otro proveedor de autenticación de terceros. Como alternativa, puede iniciar sesión con otra cuenta mediante un explorador diferente.

Pasos siguientes

Siga mi tutorial Crear una aplicación ASP.NET MVC con autenticación y base de datos SQL e implementarla en Azure App Service, que es continuación de este tutorial y donde explico lo siguiente:

  1. Cómo implementar de una aplicación de Azure
  2. Cómo proteger la aplicación con roles
  3. Cómo proteger la aplicación con los filtros RequireHttps y Authorize
  4. Cómo usar la API de pertenencia para agregar usuarios y roles

Para obtener una buena explicación de cómo funcionan los servicios de autenticación externos de ASP.NET, consulte Servicios de autenticación externos de Robert McMurray. En el artículo de Robert también se ahonda en detalles sobre cómo habilitar la autenticación de Microsoft y Twitter. En el excelente tutorial de EF/MVC de Tom Dykstra se describe cómo trabajar con Entity Framework.