> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> This guide demonstrates how to integrate Auth0 with any new or existing ASP.NET MVC application using the Auth0.AspNetCore.Authentication SDK.

# Add Login to Your ASP.NET MVC Application

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

<HowToSchema />

<Accordion title="Use AI to integrate Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  If you use an AI coding assistant like Claude Code, Cursor, or GitHub Copilot, you can add Auth0 authentication automatically in minutes using [agent skills](https://agentskills.io/home).

  **Install:**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-aspnetcore-authentication
  ```

  **Then ask your AI assistant:**

  ```text theme={null}
  Add Auth0 authentication to my ASP.NET Core MVC app
  ```

  Your AI assistant will automatically create your Auth0 application, fetch credentials, install the Auth0 ASP.NET Core Authentication SDK, configure authentication middleware, and implement login/logout flows. [Full agent skills documentation →](/docs/quickstart/agent-skills)
</Accordion>

<Note>
  **Prerequisites:** Before you begin, ensure you have the following installed:

  * **[.NET SDK](https://dotnet.microsoft.com/download)** 8.0 or newer
  * Your favorite code editor (Visual Studio, VS Code, or Rider)
  * An Auth0 account ([sign up for free](https://auth0.com/signup))
</Note>

## Get Started

Auth0 allows you to quickly add authentication and gain access to user profile information in your application. This guide demonstrates how to integrate Auth0 with any new or existing ASP.NET MVC application using the `Auth0.AspNetCore.Authentication` SDK.

<Steps>
  <Step title="Create a new project" stepNumber={1}>
    Create a new ASP.NET Core MVC project for this Quickstart

    ```shellscript theme={null}
    dotnet new mvc -n SampleMvcApp
    ```

    Open the project

    ```shellscript theme={null}
    cd SampleMvcApp
    ```
  </Step>

  <Step title="Install the Auth0 SDK" stepNumber={2}>
    ```shellscript theme={null}
    dotnet add package Auth0.AspNetCore.Authentication
    ```
  </Step>

  <Step title="Setup your Auth0 Application" stepNumber={3}>
    Next up, you need to create a new Application on your Auth0 tenant and add the configuration to your project.

    You can choose to set up your Auth0 app automatically by running a CLI command, or do it manually via the Dashboard:

    <Tabs>
      <Tab title="CLI">
        Run the following shell command on your project's root directory to create an Auth0 Application and update your `appsettings.json`:

        <CodeGroup>
          ```shellscript Mac theme={null}
          # Install Auth0 CLI (if not already installed)
          brew tap auth0/auth0-cli && brew install auth0

          # Set up Auth0 app and generate appsettings.json
          auth0 qs setup --app --type regular --framework aspnet-mvc --port 5000 --name "My ASP.NET MVC App"
          ```

          ```powershell Windows theme={null}
          # Install Auth0 CLI (if not already installed)
          scoop bucket add auth0 https://github.com/auth0/scoop-auth0-cli.git
          scoop install auth0

          # Set up Auth0 app and generate appsettings.json
          auth0 qs setup --app --type regular --framework aspnet-mvc --port 5000 --name "My ASP.NET MVC App"
          ```
        </CodeGroup>

        <Note>
          This command will:

          1. Check if you're authenticated (and prompt for login if needed)
          2. Create an Auth0 Regular Web Application configured for `http://localhost:5000`
          3. Update `appsettings.json` with `Auth0:Domain`, `Auth0:ClientId`, and `Auth0:ClientSecret`
        </Note>
      </Tab>

      <Tab title="Dashboard">
        Before you start, create or update `appsettings.json` on your project's root directory

        ```json appsettings.json theme={null}
        {
          "Logging": {
            "LogLevel": {
              "Default": "Information",
              "Microsoft.AspNetCore": "Warning"
            }
          },
          "AllowedHosts": "*",
          "Auth0": {
            "Domain": "YOUR_AUTH0_DOMAIN",
            "ClientId": "YOUR_CLIENT_ID",
            "ClientSecret": "YOUR_CLIENT_SECRET"
          }
        }
        ```

        1. Go to the [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
        2. Click **Applications → Applications → Create Application**
        3. Enter a name for your application (e.g., "My MVC App")
        4. Select **Regular Web Application** as the application type
        5. Click **Create**
        6. Go to the **Settings** tab
        7. Replace `YOUR_AUTH0_DOMAIN`, `YOUR_CLIENT_ID`, and `YOUR_CLIENT_SECRET` in the `appsettings.json` file with the **Domain**, **Client ID**, and **Client Secret** values from the dashboard
      </Tab>
    </Tabs>

    **Configure Callback URLs:**

    In the **Settings** tab, configure the following URLs:

    * **Allowed Callback URLs**: `http://localhost:5000/callback`
    * **Allowed Logout URLs**: `http://localhost:5000`
    * **Allowed Web Origins**: `http://localhost:5000`

    Click **Save Changes**

    <Info>
      **Important:** Make sure to [setup connections](https://auth0.com/docs/get-started/applications/set-up-database-connections) and enable them for your application in the Auth0 Dashboard under the **Connections** tab.
    </Info>
  </Step>

  <Step title="Configure authentication" stepNumber={4}>
    Update your `Program.cs` to configure Auth0 authentication:

    ```csharp Program.cs lines theme={null}
    using Auth0.AspNetCore.Authentication;

    var builder = WebApplication.CreateBuilder(args);

    builder.Services.AddAuth0WebAppAuthentication(options =>
    {
        options.Domain = builder.Configuration["Auth0:Domain"];
        options.ClientId = builder.Configuration["Auth0:ClientId"];
        options.ClientSecret = builder.Configuration["Auth0:ClientSecret"];
    });

    builder.Services.AddControllersWithViews();

    var app = builder.Build();

    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    app.Run();
    ```
  </Step>

  <Step title="Add Login and Logout functionality" stepNumber={5}>
    Create an `AccountController.cs` in the `Controllers` folder:

    ```csharp Controllers/AccountController.cs lines theme={null}
    using Auth0.AspNetCore.Authentication;
    using Microsoft.AspNetCore.Authentication;
    using Microsoft.AspNetCore.Authentication.Cookies;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    public class AccountController : Controller
    {
        public async Task Login(string returnUrl = "/")
        {
            var authenticationProperties = new LoginAuthenticationPropertiesBuilder()
                .WithRedirectUri(returnUrl)
                .Build();

            await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
        }

        [Authorize]
        public async Task Logout()
        {
            var authenticationProperties = new LogoutAuthenticationPropertiesBuilder()
                .WithRedirectUri(Url.Action("Index", "Home"))
                .Build();

            await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }

        [Authorize]
        public IActionResult Profile()
        {
            return View();
        }
    }
    ```
  </Step>

  <Step title="Create Profile view" stepNumber={6}>
    Create a new file `Views/Account/Profile.cshtml`:

    ```html Views/Account/Profile.cshtml lines theme={null}
    @{
        ViewData["Title"] = "User Profile";
    }

    <div class="row">
        <div class="col-md-12">
            <h2>@ViewData["Title"]</h2>
            <div class="row">
                <div class="col-md-2">
                    <img src="@User.FindFirst(c => c.Type == "picture")?.Value" alt="User's profile picture" class="img-fluid rounded-circle" />
                </div>
                <div class="col-md-10">
                    <h3>@User.Identity.Name</h3>
                    <p><strong>Email:</strong> @User.FindFirst(c => c.Type == System.Security.Claims.ClaimTypes.Email)?.Value</p>
                    <p><strong>Email Verified:</strong> @User.FindFirst(c => c.Type == "email_verified")?.Value</p>
                    <p><strong>User ID:</strong> @User.FindFirst(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier)?.Value</p>
                </div>
            </div>
            
            <h4 class="mt-4">User Claims</h4>
            <table class="table">
                <thead>
                    <tr>
                        <th>Claim Type</th>
                        <th>Claim Value</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var claim in User.Claims)
                    {
                        <tr>
                            <td>@claim.Type</td>
                            <td>@claim.Value</td>
                        </tr>
                    }
                </tbody>
            </table>
        </div>
    </div>
    ```

    <Info>
      **Note:** You'll need to create the `Views/Account` directory first if it doesn't exist.
    </Info>
  </Step>

  <Step title="Update your layout" stepNumber={7}>
    Update your layout file to add Login/Logout buttons. In `Views/Shared/_Layout.cshtml`, find the `<nav>` element and replace it with:

    ```html Views/Shared/_Layout.cshtml lines theme={null}
    <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
        <div class="container-fluid">
            <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">SampleMvcApp</a>
            <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                <ul class="navbar-nav flex-grow-1">
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                    </li>
                </ul>
                <ul class="navbar-nav">
                    @if (User.Identity.IsAuthenticated)
                    {
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-controller="Account" asp-action="Profile">@User.Identity.Name</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-controller="Account" asp-action="Logout">Logout</a>
                        </li>
                    }
                    else
                    {
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-controller="Account" asp-action="Login">Login</a>
                        </li>
                    }
                </ul>
            </div>
        </div>
    </nav>
    ```

    <Info>
      **Important:** Only replace the `<nav>` element. Keep all other parts of \_Layout.cshtml intact, especially the `@RenderBody()` call which is required for rendering page content.
    </Info>
  </Step>

  <Step title="Run your application" stepNumber={8}>
    ```shellscript theme={null}
    dotnet run
    ```

    Your application should start and display the URL it's listening on:

    ```
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://localhost:5000
    ```

    Open your browser and navigate to `http://localhost:5000`. Click the **Login** link in the navigation bar. You'll be redirected to Auth0's login page. After logging in, you'll be redirected back to your application, and you should see your name in the navigation bar.
  </Step>
</Steps>

<Check>
  **Checkpoint**

  You should now have a fully functional Auth0-protected MVC application running on [http://localhost:5000](http://localhost:5000). Users can log in, view their profile, and log out.
</Check>

***

## Advanced Usage

<Accordion title="Access User Profile Information">
  You can access user profile information through the `User` property in your controllers or views:

  ```csharp Controllers/AccountController.cs theme={null}
  [Authorize]
  public IActionResult Profile()
  {
      var user = new
      {
          Name = User.Identity.Name,
          EmailAddress = User.FindFirst(c => c.Type == System.Security.Claims.ClaimTypes.Email)?.Value,
          ProfileImage = User.FindFirst(c => c.Type == "picture")?.Value,
          UserId = User.FindFirst(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier)?.Value
      };
      
      return View(user);
  }
  ```

  The user claims contain standard OIDC information:

  * **Name**: User's display name
  * **Email**: User's email address
  * **Picture**: User's profile picture URL
  * **NameIdentifier** (sub): Unique user ID
</Accordion>

<Accordion title="Customize Login Parameters">
  You can pass custom parameters to the Auth0 login page:

  ```csharp Controllers/AccountController.cs theme={null}
  public async Task Login(string returnUrl = "/")
  {
      var authenticationProperties = new LoginAuthenticationPropertiesBuilder()
          .WithRedirectUri(returnUrl)
          .WithParameter("screen_hint", "signup")  // Show signup page
          .WithParameter("ui_locales", "es")       // Set language to Spanish
          .Build();

      await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
  }
  ```
</Accordion>

<Accordion title="Store Tokens for API Calls">
  If you need to call external APIs on behalf of the user, you can retrieve and store tokens:

  ```csharp Program.cs theme={null}
  builder.Services.AddAuth0WebAppAuthentication(options =>
  {
      options.Domain = builder.Configuration["Auth0:Domain"];
      options.ClientId = builder.Configuration["Auth0:ClientId"];
      options.ClientSecret = builder.Configuration["Auth0:ClientSecret"];
  })
  .WithAccessToken(options =>
  {
      options.Audience = "https://your-api.example.com";
  });
  ```

  Then retrieve the access token in your controller:

  ```csharp Controllers/ApiController.cs theme={null}
  [Authorize]
  public async Task<IActionResult> CallApi()
  {
      var accessToken = await HttpContext.GetTokenAsync("access_token");
      
      // Use the access token to call your API
      var client = new HttpClient();
      client.DefaultRequestHeaders.Authorization = 
          new AuthenticationHeaderValue("Bearer", accessToken);
      
      var response = await client.GetAsync("https://your-api.example.com/data");
      var data = await response.Content.ReadAsStringAsync();
      
      return View(data);
  }
  ```
</Accordion>

<Accordion title="Handle Authentication Events">
  Customize authentication behavior by handling events:

  ```csharp Program.cs theme={null}
  builder.Services.AddAuth0WebAppAuthentication(options =>
  {
      options.Domain = builder.Configuration["Auth0:Domain"];
      options.ClientId = builder.Configuration["Auth0:ClientId"];
      options.ClientSecret = builder.Configuration["Auth0:ClientSecret"];
  })
  .WithAccessToken(options =>
  {
      options.Events = new Auth0WebAppWithAccessTokenEvents
      {
          OnMissingRefreshToken = async (context) =>
          {
              await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
              var authenticationProperties = new LoginAuthenticationPropertiesBuilder()
                  .WithRedirectUri("/")
                  .Build();
              
              await context.ChallengeAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
          }
      };
  });
  ```
</Accordion>

***

## Additional Resources

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/auth0/auth0-aspnetcore-authentication">
    Source code and issue tracker
  </Card>

  <Card title="API Reference" icon="code" href="https://auth0.github.io/auth0-aspnetcore-authentication/">
    Detailed API documentation
  </Card>

  <Card title="Community Forum" icon="comments" href="https://community.auth0.com/">
    Get help from the Auth0 community
  </Card>
</CardGroup>

***

## Common Issues

<AccordionGroup>
  <Accordion title="Unable to obtain configuration">
    **Problem:** `Unable to obtain configuration from: https://your-tenant.auth0.com/.well-known/openid-configuration`

    **Solution:** Verify your Domain is correct and does not include `https://`. The library automatically constructs the authority.

    ```json theme={null}
    {
      "Auth0": {
        "Domain": "your-tenant.auth0.com"  // Correct - no protocol
      }
    }
    ```

    Also ensure:

    * No trailing slash in the domain value
    * Your application has internet access to reach Auth0
    * The domain format matches your tenant region (`.auth0.com`, `.us.auth0.com`, `.eu.auth0.com`)
  </Accordion>

  <Accordion title="Configuration values not found">
    **Problem:** `ArgumentNullException: Value cannot be null. (Parameter 'Domain')` or similar.

    **Solution:** Ensure `appsettings.json` contains the Auth0 section with Domain, ClientId, and ClientSecret values. Check that configuration is being read correctly:

    ```csharp Program.cs theme={null}
    builder.Services.AddAuth0WebAppAuthentication(options =>
    {
        options.Domain = builder.Configuration["Auth0:Domain"]
            ?? throw new InvalidOperationException("Auth0:Domain is required");
        options.ClientId = builder.Configuration["Auth0:ClientId"]
            ?? throw new InvalidOperationException("Auth0:ClientId is required");
        options.ClientSecret = builder.Configuration["Auth0:ClientSecret"]
            ?? throw new InvalidOperationException("Auth0:ClientSecret is required");
    });
    ```
  </Accordion>

  <Accordion title="Middleware order issues">
    **Problem:** Authentication not working despite correct configuration.

    **Solution:** Ensure middleware is in the correct order. `UseAuthentication()` must come before `UseAuthorization()`:

    ```csharp Program.cs theme={null}
    app.UseRouting();
    app.UseAuthentication();  // Must be before UseAuthorization
    app.UseAuthorization();
    app.MapControllerRoute(...);
    ```
  </Accordion>
</AccordionGroup>

***

## Sample Application

A sample application can be found alongside the sourcecode for the SDK:

<Card title="ASP.NET Core MVC Playgroud App" icon="github" href="https://github.com/auth0/auth0-aspnetcore-authentication/tree/main/playground/Auth0.AspNetCore.Authentication.Playground">
  Includes login, logout, user profile and other examples.
</Card>

Clone and run:

```bash theme={null}
git clone https://github.com/auth0/auth0-aspnetcore-authentication.git
cd auth0-aspnetcore-authentication/playground/Auth0.AspNetCore.Authentication.Playground
# Update appsettings.json with your Auth0 configuration
dotnet run
```

***
