首页 > 解决方案 > 登录后重复索赔?还是期间?

问题描述

我注意到,当我登录时,出于某种原因设置了重复声明,如下图所示:

在此处输入图像描述

我不确定导致此问题的原因是什么,但因此,我无法将自定义声明添加到声明列表中。最奇怪的是,这段代码通过 Github 来自另一台计算机,并且在那里工作。有没有清除cookies之类的区域?

这是我的登录代码

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

我的自定义声明 Cookie 助手:

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

可以看到,即使这段代码被注释掉了,在 cookie 助手通过之后,声明仍然是重复的。

标签: c#asp.net-core

解决方案


我不确定这在哪里引起了问题,但我自己的解决方案是清除所有现有的声明并重新添加它们

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

推荐阅读