You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Razor视图中基于策略的授权403错误排查

问题:Razor页面授权403排查

已配置Razor页面授权,但用户已持有对应声明仍返回403未授权,具体配置及代码如下:


1. Razor页面授权配置

[Authorize(Policy = ClaimsPolicies.ViewAdminClaim)]
[BindProperties]
public class EditCompanyModel(ApplicationDbContext applicationDbContext) : PageModel

2. 策略常量定义

public const string ViewAdminClaim = "View Admin Claim";

3. 授权策略启动配置

_ = services.AddAuthorization(options =>
{
    options.AddPolicy(ClaimsPolicies.ViewAdminClaim, policy => policy.RequireClaim(DefaultClaims.ViewAdminClaim, "Yes"));
});

4. 登录逻辑(LoginAsync)

public async Task<Response> LoginAsync(CookieRequest request)
{
    ApplicationUser? user = await _userManager.FindByEmailAsync(request.Email);

    if (user == null)
    {
        return Response.Fail("Invalid user");
    }

    if (user.IsActive == false)
    {
        return Response.Fail("User account deactivated");
    }

    bool passwordIsCorrect = await _userManager.CheckPasswordAsync(user, request.Password);

    if (!passwordIsCorrect)
    {
        return Response.Fail("Incorrect Password");
    }

    Claim[] customClaims = [
            new Claim("tenant", user.TenantId)
        ];

    ClaimsPrincipal claimsPrincipal = await _signInManager.CreateUserPrincipalAsync(user);
    if (claimsPrincipal.Identity is ClaimsIdentity claimsIdentity)
    {
        claimsIdentity.AddClaims(customClaims);
    }


    await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme, claimsPrincipal);


    return Response.Success();
}

5. 登录页模型

[AllowAnonymous]
public class LoginModel : PageModel
{
    public CookieRequest cookieRequest { get; set; }

    public IActionResult OnGet()
    {
        return User.Identity.IsAuthenticated ? Redirect("/") : Page();
    }
}

6. 调试获取的ClaimsPrincipal声明

"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: 778a23b9-807e-4289-a2b9-49e5f0921525"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: admin@admin.com.test"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress: admin@admin.com"
"AspNet.Identity.SecurityStamp: PJHVEWTBNDUGPV5ONJAR776VO5W6JOF7"
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role: Sys Admin"
"View Admin Claim: Yes"
"tenant: test"

7. Program.cs中间件配置

app.UseCors("defaultPolicy");
app.UseHttpsRedirection();
app.UseStatusCodePagesWithRedirects("/NotFound");
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<TenantResolver>();
app.MapRazorPages();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.MapControllers();
app.UseSession();
app.Run();

排查点:

  • ClaimType匹配一致性:检查DefaultClaims.ViewAdminClaim的字符串值是否和调试中显示的声明Type("View Admin Claim")完全一致,包括大小写、空格等细节,策略的RequireClaim对ClaimType的匹配是区分大小写的。
  • 中间件顺序错误:UseSession()当前放在MapRazorPages()之后,正确顺序应移到UseRouting()之后、UseAuthentication()之前,否则可能影响身份会话数据的读取。调整后顺序:
    app.UseRouting();
    app.UseSession();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseMiddleware<TenantResolver>();
    app.MapRazorPages();
    // 其他映射逻辑
    
  • TenantResolver中间件影响:该中间件放在授权之后,可能在授权完成后修改请求上下文导致身份信息异常,可尝试将其移到UseAuthorization()之前,或检查中间件内部是否有修改ClaimsPrincipal的逻辑。
  • 认证Scheme一致性:确认AddAuthentication()配置中默认Scheme是否为IdentityConstants.ApplicationScheme,需和登录时使用的Scheme保持一致。

内容的提问来源于stack exchange,提问作者Sanjeev-e-jeevs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:36:32