我有以下 Razor 页面:
[Authorize(Policy = ClaimsPolicies.ViewAdminClaim)]
[BindProperties]
public class EditCompanyModel(ApplicationDbContext applicationDbContext) : PageModel
其中策略来自常数:
public const string ViewAdminClaim = "View Admin Claim";
我的初创公司有这个来添加声明:
_ = services.AddAuthorization(options =>
{
options.AddPolicy(ClaimsPolicies.ViewAdminClaim, policy => policy.RequireClaim(DefaultClaims.ViewAdminClaim, "Yes"));
我的数据库看起来像这样:
用户角色:
用户ID | 角色ID |
---|---|
778a23b9-807e-4289-a2b9-49e5f0921525 | a31dd068-1c7b-48a5-97e9-a6340031fbe4 |
角色:
身份证 | 姓名 | 标准化名称 | 并发标记 |
---|---|---|---|
a31dd068-1c7b-48a5-97e9-a6340031fbe4 | 系统管理员 | 系统管理员 | 84cc866a-0087-41a9-b5e4-1d106f2ee851 |
角色声明:
身份证 | 角色ID | 索赔类型 | 索赔价值 |
---|---|---|---|
1 | a31dd068-1c7b-48a5-97e9-a6340031fbe4 | 查看管理员声明 | 是的 |
登录调试器后,我的声明将注册在以下声明主体中:
await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme, claimsPrincipal);
作为 {View Admin Claim: Yes},但是如果我尝试访问 EditCompany 页面,我会遇到 403 Unauthorized。
我是否遗漏了一张支票?
如果您可以确保您的
RoleClaims
表包含正确的角色以及您共享的声明,则您只需通过代码登录即可:
await _signInManager.PasswordSignInAsync(username, password, true, lockoutOnFailure: false);
而不是:
await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme, claimsPrincipal);
然后确保身份验证中间件 (
app.UseAuthentication()
) 位于授权中间件 (app.UseAuthorization()
) 之前。
如果你必须使用
_signInManager.Context.SignInAsync
,工作代码应该是这样的:
public async Task<IActionResult> OnPostAsync(string username, string password)
{
var user = await userManager.FindByNameAsync(username);
if (user != null && await _signInManager.CheckPasswordSignInAsync(user, password, false) == Microsoft.AspNetCore.Identity.SignInResult.Success)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
new Claim("View Admin Claim","Yes") //be sure add this line
};
var claimsIdentity = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme, claimsPrincipal);
return RedirectToPage("/WelcomeEmail");
}
return Page();
}