成功登录后添加声明并在应用程序的其他位置检索它

Jos*_*osh 22 asp.net asp.net-mvc claims-based-identity

请求我帮助实现向经过身份验证的用户分配声明的自定义方式.成功登录后,

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                //Get the user
                ApplicationUser user = UserManager.FindByEmail(model.Email);
                //Ends here
                ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
                AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);
Run Code Online (Sandbox Code Playgroud)

我使用userId从数据存储区中获取有关用户的角色和其他信息.此后,我需要在重定向到用户仪表板之前,使用电子邮件,角色,名字,姓氏,性别等信息添加有关用户的声明.这是我尝试这样做的方式,但问题是即使在登录方法添加声明后,我也无法在_loginPartial剃刀视图中检索它

例如,当我想在登录部分显示电子邮件索赔值时,就像这样

var claims = ClaimsPrincipal.Current.Claims;
    var principal = (ClaimsPrincipal)Thread.CurrentPrincipal;
    var email = principal.Claims.Where(c => c.Type == ClaimTypes.Email).Select(c => c.Value).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)

它返回null.

因此,我只能在添加它们后使用相同的登录方法访问它们,但我需要能够从应用程序的任何位置访问它们.如果能够在整个申请中的任何其他地方检索这些声明,我将非常感谢.

谢谢.

Sam*_*ari 36

您必须登录添加您的声明,而不是之后.考虑这个例子:

public async Task<ActionResult> Login(LoginViewModel model,string returnUrl)
{
    var user = UserManager.Find(model.Email, model.Password);
    if(user!=null)
    {
        var ident = UserManager.CreateIdentity(user, 
            DefaultAuthenticationTypes.ApplicationCookie);
        ident.AddClaims(new[] {
            new Claim("MyClaimName","MyClaimValue"),
            new Claim("YetAnotherClaim","YetAnotherValue"),
        });
        AuthenticationManager.SignIn(
            new AuthenticationProperties() { IsPersistent = true }, 
            ident);
        return RedirectToLocal(returnUrl);
    }
    ModelState.AddModelError("", "Invalid login attempt.");
    return View(model);
}
Run Code Online (Sandbox Code Playgroud)

现在,由于我们在登录时注入了索赔,因此我们可以随时随地访问索赔:

((ClaimsIdentity)User.Identity).FindFirst("MyClaimName");
Run Code Online (Sandbox Code Playgroud)

您也可以在ApplicationUser.GenerateUserIdentityAsync()方法中添加声明.通过在此方法中添加声明,您可以使用SignInManager.PasswordSignInAsync()方法登录用户,而无需对默认Login操作方法进行任何修改.

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity .AddClaims(new[] {
            new Claim("MyClaimName","MyClaimValue"),
            new Claim("YetAnotherClaim","YetAnotherValue"),
        });
        return userIdentity;
    }
}
Run Code Online (Sandbox Code Playgroud)


Hoo*_*ots 6

在标识2中,这非常不同,只需创建一个声明主体工厂,然后将其连接到启动的ConfigureConfigs中,如下所示...

public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<IUser, IApplicationRole>
{
    public CustomClaimsPrincipalFactory(UserManager<IUser> userManager, RoleManager<IApplicationRole> roleManager,
                                                IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, roleManager, optionsAccessor)
    {
    }

    public async override Task<ClaimsPrincipal> CreateAsync(IUser user)
    {
        var principal = await base.CreateAsync(user);

        // Add your claims here
        ((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim(ClaimTypes.Email, user.Email),
                                                                new Claim(ClaimTypes.Gender, user.Gender),
                                                                new Claim(ClaimTypes.GivenName, user.FirstName),
                                                                new Claim(ClaimTypes.Surname, user.LastName)
                                                             });

        return principal;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您就可以在调用AddIdentity之后将其连接到ConfigureServices中。

         services.AddIdentity<IUser, IApplicationRole>()
         .AddDefaultTokenProviders();


        // Add Custom Claims processor
        services.AddScoped<IUserClaimsPrincipalFactory<IUser>, CustomClaimsPrincipalFactory>();
Run Code Online (Sandbox Code Playgroud)

这是一篇关于该主题的很好的文章...

https://www.codeguru.com/csharp/csharp/cs_misc/security/asp.net-core-and-claim-based-security.html