configure-auth
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseConfigure Auth
配置身份验证
Step 1 — Read AGENTS.md
步骤1 — 阅读AGENTS.md
Read at the workspace root for the project's interactivity mode and scope before making changes.
AGENTS.md在进行更改前,请阅读工作区根目录下的文件,了解项目的交互模式和范围。
AGENTS.mdStep 2 — Register auth services in Program.cs
步骤2 — 在Program.cs中注册认证服务
csharp
// Program.cs (server project)
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthorization();For ASP.NET Core Identity add the Identity services:
csharp
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies();
builder.Services.AddIdentityCore<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager()
.AddDefaultTokenProviders();csharp
// Program.cs (服务器项目)
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthorization();若使用ASP.NET Core Identity,请添加Identity服务:
csharp
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies();
builder.Services.AddIdentityCore<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager()
.AddDefaultTokenProviders();Step 3 — Wire App.razor for auth and render mode
步骤3 — 配置App.razor以支持认证和渲染模式
The component must use and conditionally apply the render mode so that pages excluded from interactive routing render statically.
App.razorAuthorizeRouteViewrazor
<!DOCTYPE html>
<html>
<head>
<HeadOutlet @rendermode="RenderModeForPage" />
</head>
<body>
<Routes @rendermode="RenderModeForPage" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
@code {
[CascadingParameter]
public HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.AcceptsInteractiveRouting()
? InteractiveServer // replace with the app's render mode
: null;
}In (or wherever the router lives), use :
Routes.razorAuthorizeRouteViewrazor
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(Layout.MainLayout)">
<NotAuthorized>
@if (context.User.Identity?.IsAuthenticated != true)
{
<RedirectToLogin />
}
else
{
<p>You are not authorized to access this resource.</p>
}
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>App.razorAuthorizeRouteViewrazor
<!DOCTYPE html>
<html>
<head>
<HeadOutlet @rendermode="RenderModeForPage" />
</head>
<body>
<Routes @rendermode="RenderModeForPage" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
@code {
[CascadingParameter]
public HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.AcceptsInteractiveRouting()
? InteractiveServer // 替换为应用的渲染模式
: null;
}在(或路由所在的其他文件)中,使用:
Routes.razorAuthorizeRouteViewrazor
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(Layout.MainLayout)">
<NotAuthorized>
@if (context.User.Identity?.IsAuthenticated != true)
{
<RedirectToLogin />
}
else
{
<p>您无权访问此资源。</p>
}
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>Step 4 — Protect pages and components
步骤4 — 保护页面和组件
[Authorize] attribute on pages
页面上的[Authorize]特性
razor
@page "/admin"
@attribute [Authorize]With roles or policies:
razor
@attribute [Authorize(Roles = "Admin")]
@attribute [Authorize(Policy = "RequireManager")]razor
@page "/admin"
@attribute [Authorize]结合角色或策略:
razor
@attribute [Authorize(Roles = "Admin")]
@attribute [Authorize(Policy = "RequireManager")]AuthorizeView for conditional UI
使用AuthorizeView实现条件UI
razor
<AuthorizeView>
<Authorized>Welcome, @context.User.Identity?.Name!</Authorized>
<NotAuthorized><a href="Account/Login">Log in</a></NotAuthorized>
</AuthorizeView>Role/policy variants:
razor
<AuthorizeView Roles="Admin,Manager">
<Authorized>Admin content here</Authorized>
</AuthorizeView>razor
<AuthorizeView>
<Authorized>欢迎,@context.User.Identity?.Name!</Authorized>
<NotAuthorized><a href="Account/Login">登录</a></NotAuthorized>
</AuthorizeView>角色/策略变体:
razor
<AuthorizeView Roles="Admin,Manager">
<Authorized>管理员内容</Authorized>
</AuthorizeView>Access auth state in code
在代码中访问认证状态
csharp
[CascadingParameter]
private Task<AuthenticationState>? AuthState { get; set; }
protected override async Task OnInitializedAsync()
{
if (AuthState is not null)
{
var state = await AuthState;
var isAdmin = state.User.IsInRole("Admin");
}
}csharp
[CascadingParameter]
private Task<AuthenticationState>? AuthState { get; set; }
protected override async Task OnInitializedAsync()
{
if (AuthState is not null)
{
var state = await AuthState;
var isAdmin = state.User.IsInRole("Admin");
}
}Step 5 — Identity pages must stay static SSR
步骤5 — Identity页面必须保持静态SSR
SignInManagerUserManagerHttpContextIn a globally interactive app, mark every Identity page:
razor
@page "/Account/Login"
@attribute [ExcludeFromInteractiveRouting]This forces a full-page navigation (exits the interactive circuit) so the page renders through the static SSR pipeline with a real .
HttpContextApp.razorAcceptsInteractiveRouting()nullIn a per-page app, Identity pages are static by default (no directive), so is not needed.
@rendermode[ExcludeFromInteractiveRouting]SignInManagerUserManagerHttpContext在全局交互式应用中,标记所有Identity页面:
razor
@page "/Account/Login"
@attribute [ExcludeFromInteractiveRouting]这会强制触发全页面导航(退出交互式回路),使页面通过带有真实的静态SSR管道渲染。
HttpContextApp.razorAcceptsInteractiveRouting()null在按页面配置的应用中,Identity页面默认是静态的(无指令),因此不需要。
@rendermode[ExcludeFromInteractiveRouting]Step 6 — Auth state in WebAssembly / Auto mode
步骤6 — WebAssembly / Auto模式下的认证状态
WebAssembly components run in the browser and have no . Auth state must be serialized from the server during prerendering and deserialized on the client.
HttpContextServer :
Program.cscsharp
builder.Services.AddAuthenticationStateSerialization();Client :
.Client/Program.cscsharp
builder.Services.AddAuthenticationStateDeserialization();Without these calls, resolves to an anonymous user after WebAssembly takes over from prerendering.
Task<AuthenticationState>AddAuthenticationStateSerializationcsharp
builder.Services.AddAuthenticationStateSerialization(options =>
options.SerializeAllClaims = true);WebAssembly组件在浏览器中运行,没有。认证状态必须在预渲染期间从服务器序列化,然后在客户端反序列化。
HttpContext服务器端:
Program.cscsharp
builder.Services.AddAuthenticationStateSerialization();客户端:
.Client/Program.cscsharp
builder.Services.AddAuthenticationStateDeserialization();如果没有这些调用,当WebAssembly接管预渲染后,会解析为匿名用户。
Task<AuthenticationState>AddAuthenticationStateSerializationcsharp
builder.Services.AddAuthenticationStateSerialization(options =>
options.SerializeAllClaims = true);Render Mode × Auth Matrix
渲染模式 × 认证矩阵
| Render mode | HttpContext.User | SignInManager | Auth state source | Key requirement |
|---|---|---|---|---|
| Static SSR | Available | Works | Server pipeline | Use middleware for redirects, |
| Server (interactive) | NOT available | Throws | | Use |
| WebAssembly | NOT available | Throws | Serialized from server | |
| Auto | NOT available after WASM | Throws | Serialized from server | Same as WebAssembly; register in both Program.cs files |
| 渲染模式 | HttpContext.User | SignInManager | 认证状态来源 | 关键要求 |
|---|---|---|---|---|
| 静态SSR | 可用 | 正常工作 | 服务器管道 | 使用中间件进行重定向, |
| Server(交互式) | 不可用 | 抛出异常 | | 使用 |
| WebAssembly | 不可用 | 抛出异常 | 从服务器序列化而来 | 使用 |
| Auto | WASM接管后不可用 | 抛出异常 | 从服务器序列化而来 | 与WebAssembly相同;在两个Program.cs文件中注册 |
Common Mistakes
常见错误
| Mistake | Symptom | Fix |
|---|---|---|
Using | Null or stale claims | Use |
| | Move to static SSR page with |
Missing | Anonymous user after WASM loads | Add to server Program.cs; add |
| Content never shown | Static SSR uses middleware pipeline; redirect via |
Global interactivity without | Identity pages crash | Add |
Missing | | Register in Program.cs (Step 2) |
| 错误操作 | 症状 | 修复方法 |
|---|---|---|
在交互式组件中使用 | 声明为null或过期 | 使用 |
在交互式组件中使用 | | 迁移到带有 |
缺少 | WASM加载后变为匿名用户 | 在服务器端Program.cs中添加该服务;在客户端Program.cs中添加 |
在静态SSR布局中使用 | 内容从未显示 | 静态SSR使用中间件管道;通过 |
全局交互式应用未使用 | Identity页面崩溃 | 在App.razor中添加 |
缺少 | | 在Program.cs中注册该服务(步骤2) |