Agrega el inicio de sesión a tu aplicación ASP.NET OWIN
Esta guía muestra cómo integrar Auth0 con cualquier aplicación ASP.NET OWIN nueva o existente mediante el paquete NuGet Microsoft.Owin.Security.OpenIdConnect.
Auth0 te permite agregar autenticación a tu aplicación ASP.NET OWIN en minutos. Esta guía te muestra cómo agregar el inicio de sesión, el cierre de sesión y la visualización del perfil del usuario a una aplicación clásica de ASP.NET OWIN.Al final de esta guía, tu aplicación podrá:
Redirigir a los usuarios a Universal Login de Auth0 cuando inicien sesión
Procesar la devolución de llamada y almacenar la sesión en una cookie
Mostrar el nombre, el correo electrónico y la foto de perfil del usuario autenticado
Cerrar la sesión de los usuarios tanto en tu aplicación como en Auth0
Esta guía está dirigida a aplicaciones clásicas de ASP.NET (.NET Framework) que usan OWIN. Si tu aplicación ya se ejecuta en ASP.NET Core, usa el SDK Auth0.AspNetCore.Authentication en su lugar.
Una aplicación ASP.NET MVC existente destinada a .NET Framework con OWIN habilitado, o una nueva creada a partir de la plantilla ASP.NET Web Application (.NET Framework) → MVC de Visual Studio
Toda aplicación que utilice Auth0 debe registrarse en el Auth0 Dashboard. Auth0 genera un ID de cliente y un dominio que tu aplicación usa para comunicarse con Auth0.Puedes crear y configurar la aplicación de Auth0 automáticamente con la Auth0 CLI, o de forma manual desde el Dashboard:
CLI
Dashboard
Ejecuta el siguiente comando desde el directorio raíz de tu proyecto. Crea una aplicación de Auth0 y genera un fragmento de Web.config listo para pegar, con tus credenciales ya completadas:
Ejecutar el middleware de cookies de OWIN junto con las cookies de System.Web puede causar problemas. Si tienes problemas con cookies duplicadas, consulta la guía sobre problemas de integración de cookies de System.Web.
3
Configure el middleware de OWIN
El middleware de OWIN se registra en una clase de inicio. Si su proyecto ya tiene una clase de inicio de OWIN (normalmente App_Start/Startup.Auth.cs), actualice el método ConfigureAuth. Si no, cree el archivo ahora.Se requieren tanto el middleware de cookies como el middleware de OpenID Connect, y deben registrarse exactamente en este orden:
Middleware de cookies - almacena la sesión del usuario autenticado
Middleware de OpenID Connect - controla el flujo de inicio y cierre de sesión de Auth0
App_Start/Startup.Auth.cs
using System;using System.Configuration;using System.Threading.Tasks;using Microsoft.IdentityModel.Protocols.OpenIdConnect;using Microsoft.Owin;using Microsoft.Owin.Security;using Microsoft.Owin.Security.Cookies;using Microsoft.Owin.Security.OpenIdConnect;using Owin;public partial class Startup{ public void ConfigureAuth(IAppBuilder app) { var domain = ConfigurationManager.AppSettings["auth0:Domain"]; var clientId = ConfigurationManager.AppSettings["auth0:ClientId"]; // El middleware de cookies debe registrarse primero app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { AuthenticationType = "Auth0", Authority = $"https://{domain}", ClientId = clientId, ResponseType = OpenIdConnectResponseType.CodeIdToken, Scope = "openid profile email", TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { NameClaimType = "name" }, Notifications = new OpenIdConnectAuthenticationNotifications { RedirectToIdentityProvider = notification => { if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout) { // Construir la URL de cierre de sesión de Auth0 y redirigir a ella var logoutUri = $"https://{domain}/v2/logout?client_id={clientId}"; notification.Response.Redirect(logoutUri); notification.HandleResponse(); } return Task.FromResult(0); } } }); }}
Asegúrate de llamar a ConfigureAuth desde el método Configuration de tu archivo Startup.cs:
Startup.cs
using Microsoft.Owin;using Owin;[assembly: OwinStartup(typeof(Startup))]public partial class Startup{ public void Configuration(IAppBuilder app) { ConfigureAuth(app); }}
AuthenticationType se establece en "Auth0". Esta cadena se usa en el siguiente paso al desencadenar el desafío de inicio de sesión. La notificación RedirectToIdentityProvider intercepta las solicitudes de cierre de sesión y construye la URL correcta de cierre de sesión de Auth0.
4
Agregar acciones de inicio de sesión, cierre de sesión y perfil
Cree Controllers/AccountController.cs con tres métodos de acción: Login, Logout y UserProfile.
Controllers/AccountController.cs
using Microsoft.AspNetCore.Authentication;using Microsoft.AspNetCore.Authentication.Cookies;using Auth0.AspNetCore.Authentication;public class AccountController : Controller{ public ActionResult Login(string returnUrl = "/") { HttpContext.GetOwinContext().Authentication.Challenge( new AuthenticationProperties { RedirectUri = returnUrl ?? Url.Action("Index", "Home") }, "Auth0" ); } [Authorize] public ActionResult UserProfile() { var claimsIdentity = User.Identity as ClaimsIdentity; return View(new UserProfileViewModel() { Name = claimsIdentity? .FindFirst(c => c.Type == claimsIdentity.NameClaimType)?.Value, EmailAddress = claimsIdentity? .FindFirst(c => c.Type == ClaimTypes.Email)?.Value, ProfileImage = claimsIdentity? .FindFirst(c => c.Type == "picture")?.Value }); } [Authorize] public void Logout() { HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); HttpContext.GetOwinContext().Authentication.SignOut("Auth0"); }}
Cómo funciona cada acción:
Login - llama a Challenge con el esquema "Auth0". El middleware de OIDC intercepta esta llamada y redirige al usuario a Universal Login de Auth0. Después de iniciar sesión correctamente, el usuario es redirigido de nuevo a returnUrl.
UserProfile - lee los claims del usuario autenticado desde ClaimsIdentity y los pasa a la vista mediante UserProfileViewModel. El atributo [Authorize] garantiza que los usuarios no autenticados sean redirigidos primero al inicio de sesión.
Logout - llama a SignOut dos veces: una para borrar la cookie de sesión local y otra para cerrar la sesión del usuario en Auth0 (lo que también finaliza cualquier sesión activa de SSO).
Cree Models/UserProfileViewModel.cs para almacenar los datos del perfil:
Models/UserProfileViewModel.cs
public class UserProfileViewModel{ public string Name { get; set; } public string EmailAddress { get; set; } public string ProfileImage { get; set; }}
Verificación
Ejecute la aplicación y vaya a /Account/Login. Debería redirigirse a la página de Universal Login de Auth0. Después de iniciar sesión, debería volver a redirigirse a la página de inicio de su aplicación. Si aparece un error de URI de redirección, verifique que la URL de callback en la configuración de su aplicación de Auth0 coincida exactamente con la URL en la que se está ejecutando su aplicación.
5
Agregar una vista de perfil
Cree Views/Account/UserProfile.cshtml para mostrar la información del usuario autenticado:
La vista recibe un UserProfileViewModel rellenado con claims extraídos por el middleware de OIDC cuando Auth0 devuelve el token de ID.
Punto de control
Después de iniciar sesión, ve a /Account/UserProfile. Deberías ver tu nombre, correo electrónico y foto de perfil. Si el nombre o el correo electrónico aparecen vacíos, verifica que Scope en OpenIdConnectAuthenticationOptions incluya "openid profile email".
6
Añade enlaces para iniciar y cerrar sesión a tu diseño
Actualiza Views/Shared/_Layout.cshtml para mostrar enlaces para iniciar y cerrar sesión según el estado de autenticación del usuario:
Agrega esto dentro del elemento <nav> donde aparezcan los enlaces de navegación en el diseño.
Verificación
Ejecuta la aplicación. Deberías ver un enlace de Iniciar sesión en la navegación. Después de iniciar sesión, debería cambiar para mostrar tu nombre (con enlace a tu perfil) y un enlace de Cerrar sesión. Al hacer clic en Cerrar sesión, se debería cerrar la sesión y volver a la página de inicio.
Ahora tiene una integración funcional de Auth0 en su aplicación ASP.NET OWIN. Los usuarios pueden iniciar sesión mediante Universal Login de Auth0, ver su perfil y cerrar sesión.
La URI de redirección no coincide después de iniciar sesión
Problema: Auth0 muestra un error de “redirect_uri mismatch” o “callback URL mismatch” después de que el usuario inicia sesión.Solución: La URI de redirección que tu aplicación envía a Auth0 debe coincidir exactamente con una de las Allowed Callback URLs de la configuración de tu aplicación en Auth0. Verifica si hay diferencias en el protocolo (http vs https), el número de puerto, la ruta y las barras finales.
Bucle de inicio de sesión: la aplicación sigue redirigiendo a Auth0
Problema: Después de iniciar sesión correctamente, la aplicación redirige inmediatamente a Auth0 en lugar de mostrar la página autenticada.Solución: Asegúrate de que el middleware esté registrado en el orden correcto y de que la canalización de OWIN esté inicializada:
El middleware de cookies debe registrarse antes que el middleware de OpenID Connect en ConfigureAuth.
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType) debe ser la primera llamada en ConfigureAuth.
El atributo [assembly: OwinStartup(typeof(Startup))] debe estar presente para que la canalización de OWIN se inicialice correctamente.
App_Start/Startup.Auth.cs
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); // Debe ser la primera llamadaapp.UseCookieAuthentication(...); // Middleware de cookies antes de OIDCapp.UseOpenIdConnectAuthentication(...); // Middleware de OIDC después de cookies
El usuario no vuelve a la aplicación después de cerrar sesión
Problema: Al hacer clic en Cerrar sesión, se cierra la sesión del usuario en Auth0, pero no regresa a tu aplicación.Solución: Agrega un parámetro de consulta returnTo a la URL de cierre de sesión de Auth0 en la notificación RedirectToIdentityProvider. La URL de retorno también debe estar incluida en Allowed Logout URLs de la configuración de tu aplicación en Auth0:
App_Start/Startup.Auth.cs
var logoutUri = $"https://{domain}/v2/logout?client_id={clientId}&returnTo={Uri.EscapeDataString("http://localhost:3000/")}";
La imagen de perfil o el correo electrónico están vacíos
Problema:Model.ProfileImage o Model.EmailAddress es null después de iniciar sesión.Solución: Verifica que Scope en OpenIdConnectAuthenticationOptions incluya "openid profile email". El scope profile proporciona el nombre y la imagen; el scope email proporciona la dirección de correo electrónico.
App_Start/Startup.Auth.cs
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions{ Scope = "openid profile email", // Se requieren los tres alcances ...});
Los valores de dominio o del ID de cliente son null al iniciar
Problema: La aplicación genera una excepción de referencia nula o de configuración al iniciarse.Solución: Confirma que tanto auth0:Domain como auth0:ClientId existan en <appSettings> en Web.config y que estés ejecutando la configuración de compilación correcta (Debug/Release), que carga la transformación adecuada de Web.config.
Web.config
<configuration> <appSettings> <add key="auth0:Domain" value="{yourDomain}" /> <!-- No debe estar vacío --> <add key="auth0:ClientId" value="{yourClientId}" /> <!-- No debe estar vacío --> </appSettings></configuration>
Puedes pasar parámetros personalizados a la página de inicio de sesión de Auth0 modificando la notificación RedirectToIdentityProvider en Startup.Auth.cs:
App_Start/Startup.Auth.cs
RedirectToIdentityProvider = notification =>{ if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication) { // Mostrar la pantalla de registro en lugar de la de inicio de sesión notification.ProtocolMessage.SetParameter("screen_hint", "signup"); // Establecer una configuración regional específica para la interfaz notification.ProtocolMessage.SetParameter("ui_locales", "es"); } return Task.FromResult(0);}
Llamar a una API en nombre del usuario
Para llamar a una API con un token de acceso, solicita un audience y los alcances requeridos de la API durante la redirección de OIDC:
Luego, recupera el token de acceso de los claims del usuario autenticado:
Controllers/ApiController.cs
[Authorize]public async Task<ActionResult> CallApi(){ var claimsIdentity = User.Identity as ClaimsIdentity; var accessToken = claimsIdentity?.FindFirst("access_token")?.Value; var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); var response = await client.GetAsync("https://your-api.example.com/data"); // manejar la respuesta...}