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.
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.
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.
Si ha seleccionado Host en la nube, complete el cuadro de diálogo de configuración.
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):
En la siguiente imagen solo se muestran los paquetes de OWIN:
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.
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.
En el Explorador de soluciones, haga clic en el proyecto MvcAuth.
Presione la tecla F4 para ver las propiedades del proyecto. Como alternativa, en el menú Vista puede seleccionar la ventana Propiedades.
Cambie SSL habilitado a True.
Copie la dirección URL de SSL (que será
https://localhost:44300/
, a menos que haya creado otros proyectos SSL).En el Explorador de soluciones, haga clic con el botón derecho en el proyecto MvcAuth y seleccione Propiedades.
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.
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(); }
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.
Lea el cuadro de diálogo Advertencia de seguridad y después haga clic en Sí si quiere instalar el certificado que representa a localhost.
IE muestra la página Inicio , sin ninguna advertencia de SSL.
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.
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.
Navegue a la consola de desarrolladores de Google.
Si no ha creado un proyecto antes, seleccione Credenciales en la pestaña izquierda y, a continuación, seleccione Crear.
En la pestaña de la izquierda, haga clic en Credenciales.
Haga clic en Crear credenciales y, a continuación, en Id. de cliente de OAuth.
- En el cuadro de diálogo Crear Id. de cliente, mantenga la aplicación web predeterminada del tipo de aplicación.
- 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). - Establezca URI de redirección autorizado en:
https://localhost:44300/signin-google
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.
Haga clic en el elemento de menú Biblioteca, busque Google+ API, haga clic en él y presione Habilitar.
En la imagen siguiente se muestran las API habilitadas.
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.
Presione CTRL+F5 para compilar y ejecutar la aplicación. Haga clic en el vínculo Iniciar sesión .
En Utilice otro servicio para iniciar sesión, haga clic en Google.
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.
Se le redirigirá al sitio de Google, donde escribirá sus credenciales.
Una vez que haya proporcionado sus credenciales, el sistema le pedirá que le dé permisos a la aplicación web que acaba de crear:
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.
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.
Expanda DefaultConnection (MvcAuth) y Tablas, haga clic con el botón derecho en AspNetUsers y, por último, haga clic en Mostrar datos de tabla.
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.
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.
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.
- Enable-Migrations
- Add-Migration Init
- 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.
Haga clic con el botón derecho en AspNetUsuarios y haga clic en Mostrar datos de tabla.
Aquí se muestran los campos HomeTown
y BirthDate
.
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:
- Cómo implementar de una aplicación de Azure
- Cómo proteger la aplicación con roles
- Cómo proteger la aplicación con los filtros RequireHttps y Authorize
- 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.