auth0-aspnetcore-authentication

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Auth0 ASP.NET Core Web App Integration

Auth0 ASP.NET Core Web应用集成

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

使用
Auth0.AspNetCore.Authentication
为ASP.NET Core MVC、Razor Pages或Blazor Server应用添加登录、登出和用户资料功能。

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
  • ASP.NET Core应用(.NET 8或更高版本)
  • 已配置Auth0常规Web应用(非API,必须是应用类型)
  • 若尚未设置Auth0,请先使用
    auth0-quickstart
    技能

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

  • 带JWT Bearer验证的ASP.NET Core Web API - 针对受JWT保护的REST API,请使用
    auth0-aspnetcore-api
  • Blazor WebAssembly - 需要OIDC客户端认证;请查看Auth0 Blazor WebAssembly快速入门文档
  • 单页应用(SPA) - 客户端认证请使用
    auth0-react
    auth0-vue
    auth0-angular
  • Next.js应用 - 使用
    auth0-nextjs
    ,它同时支持客户端和服务端认证
  • Python Web应用 - Flask应用请使用
    auth0-flask
    ,Django应用请查看对应快速入门文档

Quick Start Workflow

快速入门流程

1. Install SDK

1. 安装SDK

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

2. Configure Credentials

2. 配置凭证

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.
将Auth0设置添加到
appsettings.json
json
{
  "Auth0": {
    "Domain": "your-tenant.us.auth0.com",
    "ClientId": "your_client_id",
    "ClientSecret": "your_client_secret"
  }
}
本地开发时,请将密钥放在源代码控制之外 - 使用
dotnet user-secrets
避免提交
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
是你的租户域名(不带
https://
)。
Auth0:ClientId
Auth0:ClientSecret
来自你的Auth0应用设置。

3. Configure Auth0 Dashboard

3. 配置Auth0控制台

In your Auth0 Application settings:
  • Allowed Callback URLs:
    http://localhost:5000/callback
  • Allowed Logout URLs:
    http://localhost:5000
  • Allowed Web Origins:
    http://localhost:5000
在你的Auth0应用设置中:
  • 允许回调URL
    http://localhost:5000/callback
  • 允许登出URL
    http://localhost:5000
  • 允许Web源
    http://localhost:5000

4. Register Auth0 in Program.cs

4. 在Program.cs中注册Auth0

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.
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();

// 标准中间件...
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();    // 必须在UseAuthorization之前调用
app.UseAuthorization();     // 重要:顺序不能颠倒

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

app.Run();
重要提示
UseAuthentication()
必须在
UseAuthorization()
之前调用。颠倒顺序会导致静默认证失败,受保护的路由永远不会触发认证挑战。

5. Create AccountController

5. 创建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.
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
方法不需要
[Authorize]
属性——它是未认证用户的入口点。
Logout
需要
[Authorize]
属性以确保仅对已认证会话触发登出操作。务必同时调用两个
SignOutAsync
方法
——仅登出Auth0方案会留下本地Cookie;仅登出Cookie方案会跳过Auth0登出URL。

6. Create Profile View

6. 创建Profile视图

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>
创建
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)

7. 更新导航栏(_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>
}
_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

8. 测试应用

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

bash
dotnet run
访问
http://localhost:5000
并点击Login启动Auth0登录流程。

Blazor Server Variant

Blazor Server变体

For Blazor Server apps, use Razor Pages as auth endpoints - Blazor components cannot perform the HTTP redirects required by OAuth challenges.
对于Blazor Server应用,请使用Razor Pages作为认证端点——Blazor组件无法执行OAuth挑战所需的HTTP重定向。

Additional Program.cs Setup

额外的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.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();
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();  // Blazor认证状态必需

builder.Services.AddRazorPages();                     // 认证端点必需

var app = builder.Build();

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

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

app.Run();

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

登录Razor页面(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);
    }
}
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)

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

        await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    }
}
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()
    {
        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)

资料组件(Components/Pages/Profile.razor)

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

更新MainLayout.razor导航

razor
@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>
razor
@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

Routes.razor

Wrap the
Router
in
CascadingAuthenticationState
to enable authorization throughout the component tree:
razor
<CascadingAuthenticationState>
    <Router AppAssembly="typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
            <FocusOnNavigate RouteData="routeData" Selector="h1" />
        </Found>
    </Router>
</CascadingAuthenticationState>

Router
包裹在
CascadingAuthenticationState
中,以便在整个组件树中启用授权:
razor
<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

Razor Pages变体

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.

对于Razor Pages应用(不含Blazor),在
Program.cs
中使用
AddRazorPages()
替代
AddControllersWithViews()
。认证端点与Blazor Server部分所示的Login/Logout页面模型相同。使用MVC部分所示的
User.Identity.IsAuthenticated
检查更新
_Layout.cshtml
中的导航。

Common Mistakes

常见错误

MistakeFix
Hardcoding
Domain
,
ClientId
, or
ClientSecret
in source
Read from configuration - use
builder.Configuration["Auth0:Domain"]
; never embed credentials
Committing
ClientSecret
to source control
Use
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
action
Login
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://
prefix
Domain
should be the bare domain, e.g.,
my-tenant.us.auth0.com
, not
https://my-tenant.us.auth0.com
Not adding
AddCascadingAuthenticationState()
in Blazor
Required 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 Blazor
Login and Logout Razor Pages won't be routed without these registrations
Using
Auth0.AspNetCore.Authentication.Api
for web apps
That package is for JWT-protected APIs - use
Auth0.AspNetCore.Authentication
for session-based web apps
Using
AddJwtBearer
instead of
AddAuth0WebAppAuthentication
AddJwtBearer
is for stateless API auth - session-based web apps require
AddAuth0WebAppAuthentication
Not creating
Views/Account/
directory for Profile view
MVC requires the directory to exist before creating the view

错误修复方案
在源代码中硬编码
Domain
ClientId
ClientSecret
从配置中读取——使用
builder.Configuration["Auth0:Domain"]
;绝不要嵌入凭证
ClientSecret
提交到源代码控制
对客户端密钥使用
dotnet user-secrets
或环境变量——绝不要提交它
UseAuthorization()
UseAuthentication()
之前调用
必须先调用
UseAuthentication()
——顺序错误会导致认证永远无法触发
仅登出一个方案务必同时调用
SignOutAsync(Auth0Constants.AuthenticationScheme)
SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme)
Login
动作添加
[Authorize]
属性
Login
必须对未认证用户可访问——仅对
Logout
Profile
应用
[Authorize]
未在Auth0控制台中配置回调URL必须将
http://localhost:5000/callback
添加到允许回调URL列表
传递带
https://
前缀的
Domain
Domain
应为纯域名,例如
my-tenant.us.auth0.com
,而非
https://my-tenant.us.auth0.com
Blazor中未添加
AddCascadingAuthenticationState()
Blazor Server必需——没有它,
AuthorizeView
[Authorize]
属性将没有认证上下文
使用Blazor组件处理登录/登出重定向Blazor组件无法执行HTTP重定向——使用Razor Pages(
/Login
/Logout
)作为认证端点
Blazor中未添加
AddRazorPages()
MapRazorPages()
没有这些注册,Login和Logout Razor Pages将无法被路由
对Web应用使用
Auth0.AspNetCore.Authentication.Api
该包用于受JWT保护的API——基于会话的Web应用请使用
Auth0.AspNetCore.Authentication
使用
AddJwtBearer
替代
AddAuth0WebAppAuthentication
AddJwtBearer
用于无状态API认证——基于会话的Web应用需要
AddAuth0WebAppAuthentication
未为Profile视图创建
Views/Account/
目录
MVC要求在创建视图前目录已存在

Key SDK Methods

关键SDK方法

Method/PropertyUsagePurpose
AddAuth0WebAppAuthentication
builder.Services.AddAuth0WebAppAuthentication(options => { ... })
Registers Auth0 cookie-based authentication
LoginAuthenticationPropertiesBuilder
new LoginAuthenticationPropertiesBuilder().WithRedirectUri(url).Build()
Builds properties for the login challenge
LogoutAuthenticationPropertiesBuilder
new LogoutAuthenticationPropertiesBuilder().WithRedirectUri(url).Build()
Builds properties for the logout redirect
ChallengeAsync
await 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.FindFirst
User.FindFirst(c => c.Type == "picture")?.Value
Accesses 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 component
Protects routes requiring authentication
AddCascadingAuthenticationState
builder.Services.AddCascadingAuthenticationState()
Required for Blazor Server auth state propagation

方法/属性使用方式用途
AddAuth0WebAppAuthentication
builder.Services.AddAuth0WebAppAuthentication(options => { ... })
注册基于Cookie的Auth0认证
LoginAuthenticationPropertiesBuilder
new LoginAuthenticationPropertiesBuilder().WithRedirectUri(url).Build()
构建登录挑战的属性
LogoutAuthenticationPropertiesBuilder
new LogoutAuthenticationPropertiesBuilder().WithRedirectUri(url).Build()
构建登出重定向的属性
ChallengeAsync
await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, props)
启动Auth0通用登录重定向
SignOutAsync
(Auth0)
await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, props)
登出Auth0并重定向到登出URL
SignOutAsync
(Cookie)
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme)
清除本地会话Cookie
User.FindFirst
User.FindFirst(c => c.Type == "picture")?.Value
在控制器/视图中访问单个用户声明
User.Identity.IsAuthenticated
@if (User.Identity.IsAuthenticated)
在视图/布局中检查认证状态
[Authorize]
控制器动作或Razor组件上的
[Authorize]
属性
保护需要认证的路由
AddCascadingAuthenticationState
builder.Services.AddCascadingAuthenticationState()
Blazor Server认证状态传播必需

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

  • auth0-aspnetcore-api
    - 用于带JWT Bearer令牌验证的ASP.NET Core Web API
  • auth0-express
    - 用于带登录/登出会话的服务器渲染Express Web应用
  • auth0-flask
    - 用于基于会话认证的Flask Web应用

Quick Reference

快速参考

SDK registration:
csharp
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:
csharp
var props = new LoginAuthenticationPropertiesBuilder().WithRedirectUri(returnUrl).Build();
await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, props);
Logout action (always call both):
csharp
var props = new LogoutAuthenticationPropertiesBuilder().WithRedirectUri(Url.Action("Index", "Home")).Build();
await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, props);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
Route protection:
csharp
[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)

SDK注册:
csharp
builder.Services.AddAuth0WebAppAuthentication(options =>
{
    options.Domain = builder.Configuration["Auth0:Domain"];        // 必填
    options.ClientId = builder.Configuration["Auth0:ClientId"];    // 必填
    options.ClientSecret = builder.Configuration["Auth0:ClientSecret"]; // 必填
});
登录动作:
csharp
var props = new LoginAuthenticationPropertiesBuilder().WithRedirectUri(returnUrl).Build();
await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, props);
登出动作(务必同时调用两个方法):
csharp
var props = new LogoutAuthenticationPropertiesBuilder().WithRedirectUri(Url.Action("Index", "Home")).Build();
await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, props);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
路由保护:
csharp
[Authorize]
public IActionResult Profile() { return View(); }
appsettings.json配置项:
  • Auth0:Domain
    - Auth0租户域名(例如
    tenant.us.auth0.com
  • Auth0:ClientId
    - 应用客户端ID
  • Auth0:ClientSecret
    - 应用客户端密钥(开发环境使用用户密钥)

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

  • 设置指南 - 自动化设置脚本、凭证配置、Auth0 CLI使用方法
  • 集成指南 - 受保护路由、API调用、Blazor模式、错误处理
  • API参考 - 完整SDK配置、构建器选项、声明参考

References

参考链接