> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

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

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  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`](https://auth0.com/docs/quickstart/webapp/aspnet-core) en su lugar.
</Callout>

<div id="prerequisites">
  ## Requisitos previos
</div>

Antes de empezar:

* Una cuenta de Auth0: [regístrate gratis](https://auth0.com/signup)
* 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
* [Visual Studio 2019 o posterior](https://visualstudio.microsoft.com/) (o cualquier IDE compatible con proyectos MVC de .NET Framework)

<div id="steps">
  ## Pasos
</div>

<Steps>
  <Step title="Configure su aplicación de Auth0">
    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:

    <Tabs>
      <Tab title="CLI">
        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:

        <Tabs>
          <Tab title="Mac/Linux">
            ```bash theme={null}
            brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && \
            AUTH0_RESULT=$(auth0 apps create \
              --name "My OWIN App" \
              --type regular \
              --auth-method post \
              --callbacks http://localhost:3000/callback \
              --logout-urls http://localhost:3000/ \
              --web-origins http://localhost:3000 \
              --reveal-secrets \
              --json \
              --metadata created_by="quickstart-docs-cli") && \
            CLIENT_ID=$(echo $AUTH0_RESULT | jq -r '.client_id') && \
            DOMAIN=$(echo $AUTH0_RESULT | jq -r '.domain') && \
            echo "Add the following to your Web.config <appSettings> section:" && \
            echo "<add key=\"auth0:Domain\" value=\"$DOMAIN\" />" && \
            echo "<add key=\"auth0:ClientId\" value=\"$CLIENT_ID\" />"
            ```
          </Tab>

          <Tab title="Windows (PowerShell)">
            ```powershell theme={null}
            $latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/auth0/auth0-cli/releases/latest"
            $latestVersion = $latestRelease.tag_name
            $version = $latestVersion -replace "^v"
            Invoke-WebRequest -Uri "https://github.com/auth0/auth0-cli/releases/download/${latestVersion}/auth0-cli_${version}_Windows_x86_64.zip" -OutFile ".\auth0.zip"
            Expand-Archive ".\auth0.zip" .\
            [System.Environment]::SetEnvironmentVariable('PATH', $Env:PATH + ";${pwd}")
            auth0 login --no-input
            $AppDetails = auth0 apps create `
              --name "My OWIN App" `
              --type regular `
              --auth-method post `
              --callbacks http://localhost:3000/callback `
              --logout-urls http://localhost:3000/ `
              --web-origins http://localhost:3000 `
              --reveal-secrets `
              --json `
              --metadata created_by="quickstart-docs-cli" | ConvertFrom-Json
            Write-Output "Add the following to your Web.config <appSettings> section:"
            Write-Output "<add key=`"auth0:Domain`" value=`"$($AppDetails.domain)`" />"
            Write-Output "<add key=`"auth0:ClientId`" value=`"$($AppDetails.client_id)`" />"
            ```
          </Tab>
        </Tabs>

        Copia las dos líneas `<add>` de la salida a la sección `<appSettings>` de tu `Web.config`:

        ```xml Web.config theme={null}
        <?xml version="1.0" encoding="utf-8"?>
        <configuration>
          <appSettings>
            <!-- pega aquí tu salida -->
          </appSettings>
        </configuration>
        ```
      </Tab>

      <Tab title="Dashboard">
        1. Ve a [Auth0 Dashboard → Applications](https://manage.auth0.com/#/applications).
        2. Haz clic en **Create Application**.
        3. Introduce un nombre para tu aplicación (por ejemplo, `My OWIN App`).
        4. Selecciona **Regular Web Application** como tipo de aplicación y haz clic en **Create**.
        5. Ve a la pestaña **Settings** y configura las siguientes URL:

        | Configuración             | Valor                            |
        | ------------------------- | -------------------------------- |
        | **Allowed Callback URLs** | `http://localhost:3000/callback` |
        | **Allowed Logout URLs**   | `http://localhost:3000/`         |
        | **Allowed Web Origins**   | `http://localhost:3000`          |

        6. Haz clic en **Save Changes**.
        7. Copia los valores de **Domain** y **Client ID** de la sección **Basic Information** y agrégalos a `Web.config`:

        ```xml Web.config theme={null}
        <?xml version="1.0" encoding="utf-8"?>
        <configuration>
          <appSettings>
            <add key="auth0:Domain" value="{yourDomain}" />
            <add key="auth0:ClientId" value="{yourClientId}" />
          </appSettings>
        </configuration>
        ```
      </Tab>
    </Tabs>

    <Info>
      Si tu aplicación se ejecuta en un puerto distinto, reemplaza `3000` por el número de puerto real en cada una de las URL anteriores.
    </Info>
  </Step>

  <Step title="Instale paquetes NuGet">
    Agrega a tu proyecto los dos paquetes de middleware de OWIN necesarios:

    | Paquete                                 | Propósito                                                                            |
    | --------------------------------------- | ------------------------------------------------------------------------------------ |
    | `Microsoft.Owin.Security.OpenIdConnect` | Controla el flujo de autenticación de OpenID Connect (OIDC) con Auth0                |
    | `Microsoft.Owin.Security.Cookies`       | Conserva la sesión del usuario en una cookie del navegador después de iniciar sesión |

    <Tabs>
      <Tab title="Consola del Administrador de paquetes">
        En Visual Studio, abre la **Consola del Administrador de paquetes** (`Tools → NuGet Package Manager → Package Manager Console`) y ejecuta:

        ```powershell theme={null}
        Install-Package Microsoft.Owin.Security.OpenIdConnect
        Install-Package Microsoft.Owin.Security.Cookies
        ```
      </Tab>

      <Tab title="CLI de dotnet">
        Desde el directorio de tu proyecto, ejecuta:

        ```bash theme={null}
        dotnet add package Microsoft.Owin.Security.OpenIdConnect
        dotnet add package Microsoft.Owin.Security.Cookies
        ```
      </Tab>
    </Tabs>

    <Info>
      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](https://github.com/aspnet/AspNetKatana/wiki/System.Web-response-cookie-integration-issues).
    </Info>
  </Step>

  <Step title="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:

    1. Middleware de cookies - almacena la sesión del usuario autenticado
    2. Middleware de OpenID Connect - controla el flujo de inicio y cierre de sesión de Auth0

    ```csharp App_Start/Startup.Auth.cs theme={null}
    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`:

    ```csharp Startup.cs theme={null}
    using Microsoft.Owin;
    using Owin;

    [assembly: OwinStartup(typeof(Startup))]

    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
    ```

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      `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.
    </Callout>
  </Step>

  <Step title="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`.

    ```csharp Controllers/AccountController.cs theme={null}
    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:

    ```csharp Models/UserProfileViewModel.cs theme={null}
    public class UserProfileViewModel
    {
        public string Name { get; set; }
        public string EmailAddress { get; set; }
        public string ProfileImage { get; set; }
    }
    ```

    <Note>
      ##### 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.
    </Note>
  </Step>

  <Step title="Agregar una vista de perfil">
    Cree `Views/Account/UserProfile.cshtml` para mostrar la información del usuario autenticado:

    ```cshtml Views/Account/UserProfile.cshtml theme={null}
    @model UserProfileViewModel
    @{
        ViewBag.Title = "User Profile";
    }

    <h2>User Profile</h2>

    <div>
        <img src='@Model.ProfileImage'
             alt="Profile picture"
             style="max-width:120px; border-radius:60px;" />
    </div>

    <ul>
        <li><strong>Name:</strong> @Model.Name</li>
        <li><strong>Email:</strong> @Model.EmailAddress</li>
    </ul>
    ```

    La vista recibe un `UserProfileViewModel` rellenado con claims extraídos por el middleware de OIDC cuando Auth0 devuelve el token de ID.

    <Note>
      ##### 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"`.
    </Note>
  </Step>

  <Step title="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:

    ```cshtml Views/Shared/_Layout.cshtml theme={null}
    @if (User.Identity.IsAuthenticated)
    {
        <a href="@Url.Action("UserProfile", "Account")">@User.Identity.Name</a>
        <a href="@Url.Action("Logout", "Account")">Log out</a>
    }
    else
    {
        <a href="@Url.Action("Login", "Account")">Log in</a>
    }
    ```

    Agrega esto dentro del elemento `<nav>` donde aparezcan los enlaces de navegación en el diseño.

    <Note>
      ##### 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.
    </Note>
  </Step>
</Steps>

<Check>
  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.
</Check>

<div id="common-issues">
  ## Problemas comunes
</div>

<AccordionGroup>
  <Accordion title="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.
  </Accordion>

  <Accordion title="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.

    ```csharp App_Start/Startup.Auth.cs theme={null}
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); // Debe ser la primera llamada

    app.UseCookieAuthentication(...);          // Middleware de cookies antes de OIDC
    app.UseOpenIdConnectAuthentication(...);   // Middleware de OIDC después de cookies
    ```
  </Accordion>

  <Accordion title="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:

    ```csharp App_Start/Startup.Auth.cs theme={null}
    var logoutUri = $"https://{domain}/v2/logout?client_id={clientId}&returnTo={Uri.EscapeDataString("http://localhost:3000/")}";
    ```
  </Accordion>

  <Accordion title="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.

    ```csharp App_Start/Startup.Auth.cs theme={null}
    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        Scope = "openid profile email",  // Se requieren los tres alcances
        ...
    });
    ```
  </Accordion>

  <Accordion title="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`.

    ```xml Web.config theme={null}
    <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>
    ```
  </Accordion>
</AccordionGroup>

<div id="advanced-usage">
  ## Uso avanzado
</div>

<Accordion title="Personalizar parámetros de inicio de sesión">
  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`:

  ```csharp App_Start/Startup.Auth.cs theme={null}
  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);
  }
  ```
</Accordion>

<Accordion title="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:

  ```csharp App_Start/Startup.Auth.cs theme={null}
  RedirectToIdentityProvider = notification =>
  {
      if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
      {
          notification.ProtocolMessage.SetParameter("audience", "https://your-api.example.com");
          notification.ProtocolMessage.Scope += " read:data";
      }

      return Task.FromResult(0);
  }
  ```

  Luego, recupera el token de acceso de los claims del usuario autenticado:

  ```csharp Controllers/ApiController.cs theme={null}
  [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...
  }
  ```
</Accordion>

***

<div id="additional-resources">
  ## Recursos adicionales
</div>

<CardGroup cols={2}>
  <Card title="Aplicación de ejemplo" icon="github" href="https://github.com/auth0-samples/auth0-aspnet-owin-mvc-samples/tree/master/Quickstart/Sample">
    Ejemplo completo y funcional de esta guía de inicio rápido
  </Card>

  <Card title="Documentación de Katana / OWIN" icon="book" href="https://learn.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/">
    Referencia oficial de Microsoft sobre OWIN/Katana
  </Card>

  <Card title="Foro de la comunidad" icon="comments" href="https://community.auth0.com/">
    Obtén ayuda de la comunidad de Auth0
  </Card>
</CardGroup>
