我们打算如何使用 IUserClaimsPrincipalFactory<T>?
How are we meant to use IUserClaimsPrincipalFactory<T>?
我对 documentation here 中描述如何使用 IUserClaimsPrincipalFactory
添加声明的示例感到困惑。
示例代码显示了如何扩展 ApplicationUser
class:
public class ApplicationUser : IdentityUser
{
public bool IsAdmin { get; set; }
}
...然后实施 UserClaimsPrincipalFactory
测试 属性 以确定要添加的声明:
if (user.IsAdmin)
{
claims.Add(new Claim(JwtClaimTypes.Role, "admin"));
}
else
{
claims.Add(new Claim(JwtClaimTypes.Role, "user"));
}
它没有说明,但我认为这意味着其他东西(未显示)将为数据库中的用户设置 IsAdmin
属性。我认为他们可以说清楚。 (此外,令人失望的是,当围绕角色与声明存在如此多的混淆时,该示例使用了角色,但我离题了...)
无论如何,我们已经根据那个新 IsAdmin
属性 的值向用户添加了一些“角色”声明。到目前为止,一切都很好。我不明白的是下一点:
The additional claim can then be used in the app. In a Razor Page, the IAuthorizationService
instance can be used to access the claim value.
听起来 Razor 页面将访问我们的声明 - 但这是代码:
@if ((await AuthorizationService.AuthorizeAsync(User, "IsAdmin")).Succeeded)
{
...
}
真的访问声明了吗?在我看来,它正在访问用户的 IsAdmin
属性。我完全看不出我们添加的声明是如何被引用的 - 除非还有其他未解释的内容。
即overload of AuthorizeAsync
将最后一个参数描述为'policyName'。我们是否打算假设有一个名为“IsAdmin”的策略来检查我们的新角色声明?
这是多么糟糕的文档 - 我忽略了它是 also in the wrong place.
的事实
It's not stated, but I think the implication is that something else (not shown) will set the IsAdmin property for a user in the database.
IsAdmin可以任意设置,比如register.Here是demo时可以设置:
在寄存器中输入型号:
public class InputModel
{
...
public bool IsAdmin { get; set; }
}
Post 处理程序:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email ,IsAdmin=Input.IsAdmin};
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
//await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
// $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
Is that really accessing the claim? It looks to me like it's accessing the IsAdmin property of the user instead. I don't see how the claim we added is referenced at all - unless there's something else that's not being explained.
That overload of AuthorizeAsync describes the last parameter as 'policyName'. Are we meant to assume that there's a policy called "IsAdmin" that checks for our new role claim?
IsAdmin
是代码中的一个策略名称,需要添加一个名称为IsAdmin
的策略,并检查其中的新角色声明。
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.AddPolicy("IsAdmin", policy => policy.RequireClaim("role", "admin"));
});
}
结果:
我对 documentation here 中描述如何使用 IUserClaimsPrincipalFactory
添加声明的示例感到困惑。
示例代码显示了如何扩展 ApplicationUser
class:
public class ApplicationUser : IdentityUser
{
public bool IsAdmin { get; set; }
}
...然后实施 UserClaimsPrincipalFactory
测试 属性 以确定要添加的声明:
if (user.IsAdmin)
{
claims.Add(new Claim(JwtClaimTypes.Role, "admin"));
}
else
{
claims.Add(new Claim(JwtClaimTypes.Role, "user"));
}
它没有说明,但我认为这意味着其他东西(未显示)将为数据库中的用户设置 IsAdmin
属性。我认为他们可以说清楚。 (此外,令人失望的是,当围绕角色与声明存在如此多的混淆时,该示例使用了角色,但我离题了...)
无论如何,我们已经根据那个新 IsAdmin
属性 的值向用户添加了一些“角色”声明。到目前为止,一切都很好。我不明白的是下一点:
The additional claim can then be used in the app. In a Razor Page, the
IAuthorizationService
instance can be used to access the claim value.
听起来 Razor 页面将访问我们的声明 - 但这是代码:
@if ((await AuthorizationService.AuthorizeAsync(User, "IsAdmin")).Succeeded)
{
...
}
真的访问声明了吗?在我看来,它正在访问用户的 IsAdmin
属性。我完全看不出我们添加的声明是如何被引用的 - 除非还有其他未解释的内容。
即overload of AuthorizeAsync
将最后一个参数描述为'policyName'。我们是否打算假设有一个名为“IsAdmin”的策略来检查我们的新角色声明?
这是多么糟糕的文档 - 我忽略了它是 also in the wrong place.
的事实It's not stated, but I think the implication is that something else (not shown) will set the IsAdmin property for a user in the database.
IsAdmin可以任意设置,比如register.Here是demo时可以设置:
在寄存器中输入型号:
public class InputModel
{
...
public bool IsAdmin { get; set; }
}
Post 处理程序:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email ,IsAdmin=Input.IsAdmin};
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
//await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
// $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
Is that really accessing the claim? It looks to me like it's accessing the IsAdmin property of the user instead. I don't see how the claim we added is referenced at all - unless there's something else that's not being explained.
That overload of AuthorizeAsync describes the last parameter as 'policyName'. Are we meant to assume that there's a policy called "IsAdmin" that checks for our new role claim?
IsAdmin
是代码中的一个策略名称,需要添加一个名称为IsAdmin
的策略,并检查其中的新角色声明。
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.AddPolicy("IsAdmin", policy => policy.RequireClaim("role", "admin"));
});
}
结果: