关于 configure-auth
用于配置 Blazor 应用身份验证的技能,指导编码 Agent 注册服务、保护路由,并按渲染模式处理 Identity 页面和身份验证状态。
主要功能
- 01注册身份验证与授权服务
- 02按角色和策略保护页面
- 03以静态 SSR 渲染 Identity 页面
- 04为 WebAssembly 和 Auto 序列化身份状态
适用场景
- 01为 Blazor 项目添加身份验证
- 02排查交互式页面中的 Identity 故障
- 03配置 WebAssembly 渲染的身份状态
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dotnet/ skills --skill configure-auth安装后在 Claude Code 中输入/configure-auth确认已加载。
详细介绍
配置身份验证
第 1 步 — 阅读 AGENTS.md
进行更改前,请先阅读工作区根目录中的 AGENTS.md,了解项目的交互模式和范围。
第 2 步 — 在 Program.cs 中注册身份验证服务
// Program.cs (server project)
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthorization();
对于 ASP.NET Core Identity,请添加 Identity 服务:
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies();
builder.Services.AddIdentityCore<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager()
.AddDefaultTokenProviders();
第 3 步 — 配置 App.razor 以支持身份验证和渲染模式
App.razor 组件必须使用 AuthorizeRouteView,并有条件地应用渲染模式,以便从交互式路由中排除的页面以静态方式呈现。
<!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;
}
在 Routes.razor(或路由器所在的位置)中,使用 AuthorizeRouteView:
<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>
第 4 步 — 保护页面和组件
在页面上使用 [Authorize] 特性
@page "/admin"
@attribute [Authorize]
使用角色或策略:
@attribute [Authorize(Roles = "Admin")]
@attribute [Authorize(Policy = "RequireManager")]
使用 AuthorizeView 实现条件式 UI
<AuthorizeView>
<Authorized>Welcome, @context.User.Identity?.Name!</Authorized>
<NotAuthorized><a href="Account/Login">Log in</a></NotAuthorized>
</AuthorizeView>
角色/策略变体:
<AuthorizeView Roles="Admin,Manager">
<Authorized>Admin content here</Authorized>
</AuthorizeView>
在代码中访问身份验证状态
[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");
}
}
第 5 步 — Identity 页面必须保持静态 SSR
SignInManager 和 UserManager 内部使用 HttpContext,并且在交互式组件中会引发异常。Identity 页面(登录、注册、管理)必须以静态 SSR 方式呈现。
在全局交互式应用中,为每个 Identity 页面添加标记:
@page "/Account/Login"
@attribute [ExcludeFromInteractiveRouting]
这会强制进行整页导航(退出交互式回路),使页面通过静态 SSR 管道呈现,并获得真实的 HttpContext。
App.razor 必须使用 AcceptsInteractiveRouting()(第 3 步),为这些页面返回 null — 否则框架仍会尝试以交互方式呈现它们。
在逐页应用中,Identity 页面默认是静态的(没有 @rendermode 指令),因此不需要 [ExcludeFromInteractiveRouting]。
第 6 步 — WebAssembly/Auto 模式下的身份验证状态
WebAssembly 组件在浏览器中运行,没有 HttpContext。身份验证状态必须在预呈现期间从服务端序列化,并在客户端反序列化。
服务端 Program.cs:
builder.Services.AddAuthenticationStateSerialization();
客户端 .Client/Program.cs:
builder.Services.AddAuthenticationStateDeserialization();
如果不调用这些方法,WebAssembly 接管预呈现后,Task<AuthenticationState> 会解析为匿名用户。
AddAuthenticationStateSerialization 接受用于包含角色和声明数据的选项:
builder.Services.AddAuthenticationStateSerialization(options =>
options.SerializeAllClaims = true);
渲染模式 × 身份验证矩阵
| 渲染模式 | HttpContext.User | SignInManager | 身份验证状态来源 | 关键要求 |
|---|---|---|---|---|
| 静态 SSR | 可用 | 正常工作 | 服务端管道 | 使用中间件进行重定向,<NotAuthorized> 不会呈现 |
| 服务端(交互式) | 不可用 | 会引发异常 | CascadingAuthenticationState | 使用 [Authorize] 和 AuthorizeView,不要使用 HttpContext |
| WebAssembly | 不可用 | 会引发异常 | 从服务端序列化 | AddAuthenticationStateSerialization/Deserialization |
| Auto | WASM 启用后不可用 | 会引发异常 | 从服务端序列化 | 与 WebAssembly 相同;在两个 Program.cs 文件中注册 |
常见错误
| 错误 | 现象 | 修复方法 |
|---|---|---|
在交互式组件中使用 HttpContext.User | 声明为空或过期 | 使用 [CascadingParameter] Task<AuthenticationState> |
在交互式组件中使用 SignInManager | InvalidOperationException | 移至带有 [ExcludeFromInteractiveRouting] 的静态 SSR 页面 |
缺少 AddAuthenticationStateSerialization | WASM 加载后显示匿名用户 | 添加到服务端 Program.cs;将 Deserialization 添加到客户端 Program.cs |
在静态 SSR 布局中使用 <NotAuthorized> | 内容始终不显示 | 静态 SSR 使用中间件管道;通过 LoginPath 或 RedirectToLogin 组件进行重定向 |
全局交互但未使用 AcceptsInteractiveRouting | Identity 页面崩溃 | 在 App.razor 中添加 AcceptsInteractiveRouting() 检查(第 3 步) |
缺少 AddCascadingAuthenticationState() | Task<AuthenticationState> 为 null | 在 Program.cs 中注册(第 2 步) |