Duplicate Claims after logging in? Or during?

2019-09-21 12:25发布

I noticed that when I am logging in, duplicate claims are being set for some reason like in this image:

enter image description here

I'm not sure what is the cause of this issue but as a result, I am unable to add custom claims to the claims list. The strangest thing is that this code came from another computer via Github and it worked there. Is there an area to clear cookies or something?

This is my login code

namespace Application.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LoginModel : PageModel
    {
        private readonly SignInManager<ApplicationUsers> _signInManager;
        private readonly UserManager<ApplicationUsers> _userManager;
        private readonly ApplicationUsersData applicationUsersData;
        private readonly CustomClaimsCookieSignInHelper<ApplicationUsers> _customClaimsCookieSignInHelper;
        private readonly UserRolesData userRolesData;
        private readonly ILogger<LoginModel> _logger;
        private List<Claim> claims = new List<Claim>();
        [BindProperty]
        public LoginViewModel Input { get; set; }
        public string ReturnUrl { get; set; }
        [TempData]
        public string ErrorMessage { get; set; }

        public LoginModel(SignInManager<ApplicationUsers> signInManager, CustomClaimsCookieSignInHelper<ApplicationUsers> _customClaimsCookieSignInHelper, UserManager<ApplicationUsers> userManager, ApplicationUsersData applicationUsersData, UserRolesData userRolesData, ILogger<LoginModel> logger)
        {
            _signInManager = signInManager;
            _userManager = userManager;
            _logger = logger;
            this.applicationUsersData = applicationUsersData;
            this.userRolesData = userRolesData;
            this._customClaimsCookieSignInHelper = _customClaimsCookieSignInHelper;
        }

        public async Task OnGetAsync(string returnUrl = null)
        {
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ModelState.AddModelError(string.Empty, ErrorMessage);
            }

            returnUrl = returnUrl ?? Url.Content("~/");

            // Clear the existing external cookie to ensure a clean login process
            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
            ReturnUrl = returnUrl;
        }

        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");

            if (ModelState.IsValid)
            {
                // This doesn't count login failures towards account lockout
                // To enable password failures to trigger account lockout, set lockoutOnFailure: true
                var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);
                if (result.Succeeded)
                {
                    var avm = applicationUsersData.GetByUsername(Input.Email);
                    var user = applicationUsersData.Get(avm.Id);
                    var roles = userRolesData.GetUserRoles(user.Id);
                    foreach (var item in roles)
                    {
                        var currentItem = new UserRoleDetailsViewModel
                        {
                            Id = item.Id,
                            Name = item.Name,
                            ApplicationId = item.ApplicationId,
                            ApplicationName = item.ApplicationName
                        };
                        var convertedItem = JsonConvert.SerializeObject(currentItem);
                        claims.Add(new Claim("Roles", convertedItem));
                    }
                    await _customClaimsCookieSignInHelper.SignInUserAsync(user, Input.RememberMe, claims);
                    _logger.LogInformation("User logged in.");
                    return LocalRedirect(returnUrl);
                }
                if (result.IsLockedOut)
                {
                    _logger.LogWarning("User account locked out.");
                    return RedirectToPage("./Lockout");
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return Page();
                }
            }
            // If we got this far, something failed, redisplay form
            return Page();
        }
    }
}

My Custom Claims Cookie Helper:

public class CustomClaimsCookieSignInHelper<TIdentityUser> where TIdentityUser : IdentityUser
{

    private readonly SignInManager<TIdentityUser> _signInManager;

    public CustomClaimsCookieSignInHelper(SignInManager<TIdentityUser> signInManager)
    {
        _signInManager = signInManager;
    }

    public async Task SignInUserAsync(TIdentityUser user, bool isPersistent, IEnumerable<Claim> customClaims)
    {
        //var claimsPrincipal = await _signInManager.CreateUserPrincipalAsync(user);
        //if (customClaims != null && claimsPrincipal?.Identity is ClaimsIdentity claimsIdentity)
        //{
        //    claimsIdentity.AddClaims(customClaims);
        //}
        //await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme,
        //    claimsPrincipal,
        //    new AuthenticationProperties { IsPersistent = isPersistent });
    }
}

As you can see, even if this code is commented, after the cookie helper has been passed through, the claims are still duplicated.

1条回答
男人必须洒脱
2楼-- · 2019-09-21 12:47

I'm not sure where this is causing issues but the solution I had to myself was to clear all the existing claims and just re-add them

var claimsPrincipal = await _signInManager.CreateUserPrincipalAsync(user);
var identity = claimsPrincipal.Identity as ClaimsIdentity;
var claims = (from c in claimsPrincipal.Claims select c).ToList();
foreach(var item in claims)
{
    identity.RemoveClaim(item);
}
if (customClaims != null)
{
    identity.AddClaims(customClaims);
}
查看更多
登录 后发表回答