mcpField
C
configure-auth

configure-auth

github.com/dotnet安全5.8k3.3k 次安装1 天前更新
代码仓库

关于 configure-auth

用于配置 Blazor 应用身份验证的技能,指导编码 Agent 注册服务、保护路由,并按渲染模式处理 Identity 页面和身份验证状态。

主要功能

  1. 01注册身份验证与授权服务
  2. 02按角色和策略保护页面
  3. 03以静态 SSR 渲染 Identity 页面
  4. 04为 WebAssembly 和 Auto 序列化身份状态

适用场景

  1. 01为 Blazor 项目添加身份验证
  2. 02排查交互式页面中的 Identity 故障
  3. 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.UserSignInManager身份验证状态来源关键要求
静态 SSR可用正常工作服务端管道使用中间件进行重定向,<NotAuthorized> 不会呈现
服务端(交互式)不可用会引发异常CascadingAuthenticationState使用 [Authorize] 和 AuthorizeView,不要使用 HttpContext
WebAssembly不可用会引发异常从服务端序列化AddAuthenticationStateSerialization/Deserialization
AutoWASM 启用后不可用会引发异常从服务端序列化与 WebAssembly 相同;在两个 Program.cs 文件中注册

常见错误

错误现象修复方法
在交互式组件中使用 HttpContext.User声明为空或过期使用 [CascadingParameter] Task<AuthenticationState>
在交互式组件中使用 SignInManagerInvalidOperationException移至带有 [ExcludeFromInteractiveRouting] 的静态 SSR 页面
缺少 AddAuthenticationStateSerializationWASM 加载后显示匿名用户添加到服务端 Program.cs;将 Deserialization 添加到客户端 Program.cs
在静态 SSR 布局中使用 <NotAuthorized>内容始终不显示静态 SSR 使用中间件管道;通过 LoginPath 或 RedirectToLogin 组件进行重定向
全局交互但未使用 AcceptsInteractiveRoutingIdentity 页面崩溃在 App.razor 中添加 AcceptsInteractiveRouting() 检查(第 3 步)
缺少 AddCascadingAuthenticationState()Task<AuthenticationState> 为 null在 Program.cs 中注册(第 2 步)

评论

支持 Markdown