Implementing custom claim with extended MVC Core Identity user

前端 未结 1 1195
-上瘾入骨i
-上瘾入骨i 2020-12-29 10:36

How can I create a custom authorize claim in MVC Core 2.0 (using AspNetCore.identity) to verify a custom user boolean property? I have extended the IdentityUser (Applicatio

相关标签:
1条回答
  • 2020-12-29 11:13

    So, you need to create custom claims somewhere and then check it through a custom policy or manually.

    1) Custom claims adding

    JwtBearer authentication

    You can do something like this:

    In your controller action that returns jwt-token you can add your 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);
    }
    

    ASP.NET Core Identity authentication

    You need to implement a custom IUserClaimsPrincipalFactory or use UserClaimsPrincipalFactory as a base class:

    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;
        }
    }
    

    then you need to register it in Startup.ConfigureServices:

    services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, ApplicationClaimsIdentityFactory>();
    

    2) Check the claim

    Custom policy

    In Startup.ConfigureServices:

    services.AddAuthorization(options =>
    {
        options.AddPolicy("Developer", policy =>
                            policy.RequireClaim("IsDeveloper", "true"));
    });
    

    and protect your action for developers:

    [Authorize(Policy = "Developer"), HttpGet]
    public string DeveloperSecret()
    {
        return "Hello Developer"
    }
    

    Check the claim manually

    Somewhere in the controller:

    bool isDeveloper = User.Claims.Any(c => c.Type == "IsDeveloper" && c.Value == "true")
    

    If you are using some other authentication the idea should be the same.

    0 讨论(0)
提交回复
热议问题