Claude
Skills
Sign in
Back

auth0-aspnetcore-authentication

Included with Lifetime
$97 forever

Use when adding login, logout, and user profile to an ASP.NET Core MVC, Razor Pages, or Blazor Server web application using cookie-based authentication - integrates Auth0.AspNetCore.Authentication for server-rendered apps with login/callback/profile/logout flows.

General

What this skill does


# Auth0 ASP.NET Core Web App Integration

Add login, logout, and user profile to an ASP.NET Core MVC, Razor Pages, or Blazor Server application using `Auth0.AspNetCore.Authentication`.

---

## Prerequisites

- ASP.NET Core application (.NET 8 or higher)
- Auth0 Regular Web Application configured (not an API - must be an Application)
- If you don't have Auth0 set up yet, use the `auth0-quickstart` skill first

## When NOT to Use

- **ASP.NET Core Web APIs with JWT Bearer validation** - Use `auth0-aspnetcore-api` for JWT-protected REST APIs
- **Blazor WebAssembly** - Requires OIDC client-side auth; see the Auth0 Blazor WebAssembly quickstart
- **Single Page Applications** - Use `auth0-react`, `auth0-vue`, or `auth0-angular` for client-side auth
- **Next.js applications** - Use `auth0-nextjs` which handles both client and server
- **Python web apps** - Use `auth0-flask` for Flask or see the Django quickstart

---

## Quick Start Workflow

### 1. Install SDK

```bash
dotnet add package Auth0.AspNetCore.Authentication
```

### 2. Configure Credentials

Add Auth0 settings to `appsettings.json`:

```json
{
  "Auth0": {
    "Domain": "your-tenant.us.auth0.com",
    "ClientId": "your_client_id",
    "ClientSecret": "your_client_secret"
  }
}
```

**For local development**, keep secrets out of source control - use `dotnet user-secrets` to avoid committing `ClientSecret`:

```bash
dotnet user-secrets set "Auth0:Domain" "your-tenant.us.auth0.com"
dotnet user-secrets set "Auth0:ClientId" "your_client_id"
dotnet user-secrets set "Auth0:ClientSecret" "your_client_secret"
```

`Auth0:Domain` is your tenant domain (without `https://`). `Auth0:ClientId` and `Auth0:ClientSecret` come from your Auth0 Application settings.

### 3. Configure Auth0 Dashboard

In your Auth0 Application settings:
- **Allowed Callback URLs**: `http://localhost:5000/callback`
- **Allowed Logout URLs**: `http://localhost:5000`
- **Allowed Web Origins**: `http://localhost:5000`

### 4. Register Auth0 in Program.cs

```csharp
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();

// Standard middleware...
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();    // Must come before UseAuthorization
app.UseAuthorization();     // Critical: order matters

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

app.Run();
```

**Critical:** `UseAuthentication()` must come before `UseAuthorization()`. Reversing these causes silent auth failures where protected routes are never challenged.

### 5. Create AccountController

```csharp
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();
    }
}
```

`Login` does not need `[Authorize]` - it is the entry point for unauthenticated users. `Logout` requires `[Authorize]` to ensure the sign-out only fires for authenticated sessions. **Always call both `SignOutAsync` methods** - signing out of only the Auth0 scheme leaves a local cookie; signing out of only the cookie scheme skips the Auth0 logout URL.

### 6. Create Profile View

Create `Views/Account/Profile.cshtml`:

```html
@{
    ViewData["Title"] = "User Profile";
}

<div class="row">
    <div class="col-md-2">
        <img src="@User.FindFirst(c => c.Type == "picture")?.Value"
             alt="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>User ID:</strong>
           @User.FindFirst(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier)?.Value</p>
    </div>
</div>

<h4 class="mt-4">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>
```

### 7. Update Navigation (_Layout.cshtml)

Add login/logout/profile links to your nav bar inside `_Layout.cshtml`:

```html
@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>
}
```

### 8. Test the App

```bash
dotnet run
```

Visit `http://localhost:5000` and click Login to start the Auth0 login flow.

---

## Blazor Server Variant

For Blazor Server apps, use Razor Pages as auth endpoints - Blazor components cannot perform the HTTP redirects required by OAuth challenges.

### Additional Program.cs Setup

```csharp
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.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddCascadingAuthenticationState();  // Required for Blazor auth state
builder.Services.AddRazorPages();                     // Required for auth endpoints

var app = builder.Build();

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

app.MapRazorPages();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();
```

### Login Razor Page (Pages/Login.cshtml.cs)

```csharp
using Auth0.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

public class LoginModel : PageModel
{
    public async Task OnGet(string returnUrl = "/")
    {
        var authenticationProperties = new LoginAuthenticationPropertiesBuilder()
            .WithRedirectUri(returnUrl)
            .Build();

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

### Logout Razor Page (Pages/Logout.cshtml.cs)

```csharp
using Auth0.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

public class LogoutModel : PageModel
{
    public async Task OnGet()
    {
       

Related in General