c# - 登录后重复索赔?还是期间?
问题描述
我注意到,当我登录时,出于某种原因设置了重复声明,如下图所示:
我不确定导致此问题的原因是什么,但因此,我无法将自定义声明添加到声明列表中。最奇怪的是,这段代码通过 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 助手通过之后,声明仍然是重复的。
解决方案
我不确定这在哪里引起了问题,但我自己的解决方案是清除所有现有的声明并重新添加它们
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);
}
推荐阅读
- flutter - Flutter Unhandled Exception: FormatException: Invalid date format
- python - 假设在 smart_open (python) 中的 AWS 角色不起作用
- mysql - 重启后无法在 mysql db 上创建用户或授予权限
- python - crypt.crypt 引发 OSError: Invalid Argument
- elasticsearch - fluentd可以使用elasticsearch插件轮换日志吗?
- ruby-on-rails - 来自具有许多子关联的父记录的 Rails csv 行
- r - 具有重叠日期的 10 天间隔
- python - 没有转换器库的 BERT 标记器和模型
- python - 根据熊猫数据框中滚动窗口内满足的一组条件创建一个布尔列
- javascript - 如何在网格中画线?