使用扩展的MVC Core Identity用户实现自定义声明

dav*_*459 8 claims-based-identity asp.net-identity asp.net-core-mvc asp.net-core

如何在MVC Core 2.0中创建自定义授权声明(使用AspNetCore.identity)来验证自定义用户布尔属性?我已经扩展了IdentityUser(ApplicationUser)以包含一个布尔值"IsDeveloper".我正在使用基于声明的身份验证,并希望添加自定义声明,但我不确定从哪里开始.如何创建自定义声明:

  1. 找到当前(自定义)Core.Identity用户.
  2. 评估自定义标识用户bool值?

我理解核心身份声称MSDN:基于声明的身份验证,但我不熟悉自定义声明,所以我不知道从哪里开始.我找到的在线文档不起作用或不适合我的场景.

Alb*_*rtK 15

因此,您需要在某处创建自定义声明,然后通过自定义策略或手动检查它.

1)自定义声明添加

JwtBearer认证

你可以这样做:

在您的控制器操作中,返回jwt-token,您可以添加custom claim:

[HttpGet]
public dynamic GetToken(string login, string password)
{
    var handler = new JwtSecurityTokenHandler();

    var sec = "12312313212312313213213123123132123123132132132131231313212313232131231231313212313213132123131321313213213131231231213213131311";
    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(sec));
    var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);

    var user = GetUserFromDb(login);
    var identity = new ClaimsIdentity(new GenericIdentity(user.Email), new[] { new Claim("user_id", user.Id) });
    if (user.IsDeveloper)
        identity.AddClaim(new Claim("IsDeveloper", "true"));
    var token = handler.CreateJwtSecurityToken(subject: identity,
                                               signingCredentials: signingCredentials,
                                               audience: "ExampleAudience",
                                               issuer: "ExampleIssuer",
                                               expires: DateTime.UtcNow.AddSeconds(100));
    return handler.WriteToken(token);
}
Run Code Online (Sandbox Code Playgroud)

ASP.NET核心身份验证

您需要实现自定义IUserClaimsPrincipalFactoryUserClaimsPrincipalFactory用作基类:

public class ApplicationClaimsIdentityFactory: Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory <ApplicationUser>
{
    UserManager<ApplicationUser> _userManager;
    public ApplicationClaimsIdentityFactory(UserManager<ApplicationUser> userManager, 
        IOptions<IdentityOptions> optionsAccessor):base(userManager, optionsAccessor)
    {}
    public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        var principal = await base.CreateAsync(user);
        if (user.IsDeveloper)
        {
          ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
              new Claim("IsDeveloper", "true")
          });
        }
        return principal;
    }
}
Run Code Online (Sandbox Code Playgroud)

那么你需要注册Startup.ConfigureServices:

services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, ApplicationClaimsIdentityFactory>();
Run Code Online (Sandbox Code Playgroud)

2)检查索赔

自定义政策

Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.AddPolicy("Developer", policy =>
                      policy.RequireClaim("IsDeveloper", "true"));
});
Run Code Online (Sandbox Code Playgroud)

并保护您的开发人员的行动:

[Authorize(Policy = "Developer"), HttpGet]
public string DeveloperSecret()
{
    return "Hello Developer"
}
Run Code Online (Sandbox Code Playgroud)

手动检查索赔

在控制器的某个地方:

bool isDeveloper = User.Claims.Any(c => c.Type == "IsDeveloper" && c.Value == "true")
Run Code Online (Sandbox Code Playgroud)

如果您正在使用其他身份验证,则该想法应该相同.

  • 我建议覆盖 `GenerateClaimsAsync` 而不是 `CreateAsync`。那么就不需要将 `principal.Identity` 转换为 `ClaimsIdentity` (3认同)