auth0-aspnetcore-authentication

oleh auth0

Use when adding cookie-based login, logout, or user profile to an ASP.NET Core MVC, Razor Pages, or Blazor Server web app. Integrates…

npx skills add https://github.com/auth0/agent-skills --skill auth0-aspnetcore-authentication

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

dotnet add package Auth0.AspNetCore.Authentication

2. Configure Credentials

Add Auth0 settings to appsettings.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:

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

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

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:

@{
    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:

@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

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

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)

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)

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()
    {
        var authenticationProperties = new LogoutAuthenticationPropertiesBuilder()
            .WithRedirectUri(Url.Content("~/"))
            .Build();

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

Profile Component (Components/Pages/Profile.razor)

@page "/profile"
@attribute [Authorize]
@using System.Security.Claims

<h1>Profile</h1>

<AuthorizeView>
    <Authorized>
        <div class="row">
            <div class="col-2">
                <img src="@context.User.FindFirst("picture")?.Value"
                     alt="Profile" class="img-fluid rounded-circle" />
            </div>
            <div class="col-10">
                <h3>@context.User.Identity?.Name</h3>
                <p><strong>Email:</strong> @context.User.FindFirst(ClaimTypes.Email)?.Value</p>
            </div>
        </div>

        <h4 class="mt-4">Claims</h4>
        <table class="table">
            <thead><tr><th>Type</th><th>Value</th></tr></thead>
            <tbody>
                @foreach (var claim in context.User.Claims)
                {
                    <tr><td>@claim.Type</td><td>@claim.Value</td></tr>
                }
            </tbody>
        </table>
    </Authorized>
</AuthorizeView>

Update MainLayout.razor Navigation

@using Microsoft.AspNetCore.Components.Authorization

<AuthorizeView>
    <Authorized>
        <a href="/profile">@context.User.Identity?.Name</a>
        <a href="/Logout">Logout</a>
    </Authorized>
    <NotAuthorized>
        <a href="/Login">Login</a>
    </NotAuthorized>
</AuthorizeView>

Routes.razor

Wrap the Router in CascadingAuthenticationState to enable authorization throughout the component tree:

<CascadingAuthenticationState>
    <Router AppAssembly="typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
            <FocusOnNavigate RouteData="routeData" Selector="h1" />
        </Found>
    </Router>
</CascadingAuthenticationState>

Razor Pages Variant

For Razor Pages apps (without Blazor), use AddRazorPages() instead of AddControllersWithViews() in Program.cs. Auth endpoints are the same Login/Logout page models shown in the Blazor Server section. Replace navigation in _Layout.cshtml using the same User.Identity.IsAuthenticated check shown in the MVC section.


Common Mistakes

MistakeFix
Hardcoding Domain, ClientId, or ClientSecret in sourceRead from configuration - use builder.Configuration["Auth0:Domain"]; never embed credentials
Committing ClientSecret to source controlUse dotnet user-secrets or environment variables for the client secret - never commit it
UseAuthorization() before UseAuthentication()Must call UseAuthentication() first - wrong order causes auth to never fire
Signing out of only one schemeAlways call both SignOutAsync(Auth0Constants.AuthenticationScheme) and SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme)
Adding [Authorize] to the Login actionLogin must be accessible to unauthenticated users - only apply [Authorize] to Logout and Profile
Not configuring Callback URLs in Auth0 DashboardMust add http://localhost:5000/callback to Allowed Callback URLs
Passing Domain with https:// prefixDomain should be the bare domain, e.g., my-tenant.us.auth0.com, not https://my-tenant.us.auth0.com
Not adding AddCascadingAuthenticationState() in BlazorRequired for Blazor Server - without it, AuthorizeView and [Authorize] attributes have no auth context
Using Blazor components for login/logout redirectsBlazor components cannot perform HTTP redirects - use Razor Pages (/Login, /Logout) for auth endpoints
Not adding AddRazorPages() and MapRazorPages() in BlazorLogin and Logout Razor Pages won't be routed without these registrations
Using Auth0.AspNetCore.Authentication.Api for web appsThat package is for JWT-protected APIs - use Auth0.AspNetCore.Authentication for session-based web apps
Using AddJwtBearer instead of AddAuth0WebAppAuthenticationAddJwtBearer is for stateless API auth - session-based web apps require AddAuth0WebAppAuthentication
Not creating Views/Account/ directory for Profile viewMVC requires the directory to exist before creating the view

Key SDK Methods

Method/PropertyUsagePurpose
AddAuth0WebAppAuthenticationbuilder.Services.AddAuth0WebAppAuthentication(options => { ... })Registers Auth0 cookie-based authentication
LoginAuthenticationPropertiesBuildernew LoginAuthenticationPropertiesBuilder().WithRedirectUri(url).Build()Builds properties for the login challenge
LogoutAuthenticationPropertiesBuildernew LogoutAuthenticationPropertiesBuilder().WithRedirectUri(url).Build()Builds properties for the logout redirect
ChallengeAsyncawait HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, props)Initiates the Auth0 Universal Login redirect
SignOutAsync (Auth0)await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, props)Signs out of Auth0 and redirects to logout URL
SignOutAsync (Cookie)await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme)Clears the local session cookie
User.FindFirstUser.FindFirst(c => c.Type == "picture")?.ValueAccesses individual user claims in controllers/views
User.Identity.IsAuthenticated@if (User.Identity.IsAuthenticated)Checks authentication state in views/layouts
[Authorize][Authorize] attribute on controller action or Razor componentProtects routes requiring authentication
AddCascadingAuthenticationStatebuilder.Services.AddCascadingAuthenticationState()Required for Blazor Server auth state propagation

Related Skills

  • auth0-aspnetcore-api - For ASP.NET Core Web APIs with JWT Bearer token validation
  • auth0-express - For server-rendered Express web apps with login/logout sessions
  • auth0-flask - For Flask web applications with session-based auth

Quick Reference

SDK registration:

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

Login action:

var props = new LoginAuthenticationPropertiesBuilder().WithRedirectUri(returnUrl).Build();
await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, props);

Logout action (always call both):

var props = new LogoutAuthenticationPropertiesBuilder().WithRedirectUri(Url.Action("Index", "Home")).Build();
await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, props);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

Route protection:

[Authorize]
public IActionResult Profile() { return View(); }

appsettings.json configuration keys:

  • Auth0:Domain - Auth0 tenant domain (e.g., tenant.us.auth0.com)
  • Auth0:ClientId - Application client ID
  • Auth0:ClientSecret - Application client secret (use user-secrets in development)

Detailed Documentation

  • Setup Guide - Automated setup scripts, credential configuration, Auth0 CLI usage
  • Integration Guide - Protected routes, calling APIs, Blazor patterns, error handling
  • API Reference - Complete SDK configuration, builder options, claims reference

References

Lebih banyak skill dari auth0

acul-screen-generator
auth0
Menghasilkan implementasi layar Auth0 Advanced Custom Universal Login (ACUL) yang lengkap dan bermerek menggunakan React atau Vanilla JS SDK. Gunakan ketika pengembang meminta untuk…
official
auth0-android-major-migration
auth0
Use when upgrading an Android app's Auth0 SDK (com.auth0.android:auth0) to the next major version. Detects the current version, checks prerequisites, and…
official
auth0-branding
auth0
Use when customizing the look of Auth0 Universal Login to match a brand — changing colors, logo, fonts, page layout, or login text. Also use when resetting…
official
auth0-custom-domains
auth0
Use when setting up, verifying, or troubleshooting a custom Auth0 login domain (e.g. login.example.com). Covers CNAME setup, verification, TLS policy, Multiple…
official
auth0-dpop
auth0
Use when adding DPoP (Demonstrating Proof-of-Possession) token binding to protect API calls with device-bound, sender-constrained access tokens that cannot be…
official
auth0-fastify
auth0
Gunakan saat menambahkan autentikasi (login, logout, rute yang dilindungi) ke aplikasi web Fastify - mengintegrasikan @auth0/auth0-fastify untuk autentikasi berbasis sesi. Untuk…
official
auth0-fastify-api
auth0
Gunakan saat mengamankan titik akhir API Fastify dengan validasi token JWT Bearer, pemeriksaan lingkup/izin, atau autentikasi tanpa status - mengintegrasikan @auth0/auth0-fastify-api untuk…
official
auth0-flutter-native
auth0
Use when adding Auth0 login, logout, or biometric-protected credential storage to a Flutter mobile app (iOS or Android). Integrates auth0_flutter on the native…
official