登录后添加用户声明或根据用户选择更改声明数据



我有一个带有 Identity 的净核心 2.1 项目。

我正在尝试使用声明作为存储一些用户数据的一种方式,基本上是他们有一些选择。

当用户首次登录时,该选项设置为查询选项并获取 0 索引,但稍后从 razor 页面用户可以更改它。

现在,我需要从登录时刷新声明数据,然后插入新选项。

问题 1.当我更改 SwitchChoice 中的值时,它会被 UserClaimsFactory 覆盖,因为我是"RefreshSignInAsync",那么如何删除旧的声明并为该用户添加新的声明?

问题 2.附带问题,以下方法是否不会在数据库中创建索赔记录,它只会在 cookie 中创建数据,对吗?

启动.cs配置为:

services.AddScoped<IUserClaimsPrincipalFactory<AppUser>, UserClaimsFactory>();

用户声明工厂.cs 已配置:

public class UserClaimsFactory : UserClaimsPrincipalFactory<AppUser, IdentityRole>
{
private IConfiguration Configuration;
private ApplicationDbContext _context;
public UserClaimsFactory(
UserManager<AppUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor,
IConfiguration config,
ApplicationDbContext context)
: base(userManager, roleManager, optionsAccessor)
{
Configuration = config;
_context = context;
}
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(AppUser user)
{
var idx = user.Id;
List<UserChoise> ret = await _context.UserChoise.Where(s => s.AppUserId == idx)
.Include(s => s.InnerChoise).OrderBy(s => s.CDate)
.ToListAsync();
if (ret!=null && ret.Count>0) { 
var identity = await base.GenerateClaimsAsync(user);
identity.AddClaim(new Claim("ABC", ret.Count > 0 ? ret[0].Name.ToString() : "NA"));
identity.AddClaim(new Claim("XYZ", ret.Count > 0 ? ret[0].Phome.ToString() : "NA"));
return identity;
}
return null;
}
}

登录.cs配置为:

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 user = await _userManager.FindByNameAsync(Input.Email);
if (!user.Active)
{
await _signInManager.SignOutAsync();
return RedirectToPage("/Index");
}
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
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();
}

SwitchChoice.cs 配置:

public async Task<IActionResult> OnPostAsync()
{
var curUser = await _userManager.GetUserAsync(User);
if (!ModelState.IsValid)
{
return Page();
}
var identity = User.Identity as ClaimsIdentity;
var existingClaim = identity.FindFirst("ABC");
if (existingClaim != null)
identity.RemoveClaim(existingClaim);
var existingClaim2 = identity.FindFirst("XYZ");
if (existingClaim2 != null)
identity.RemoveClaim(existingClaim2);

identity.AddClaim(new Claim("ABC", newVal1 != "" ? newVal1 : "NA"));
identity.AddClaim(new Claim("XYZ", newVal2 != "" ? newVal2 : "NA"));
await _signInManager.RefreshSignInAsync(curUser);
return RedirectToPage("/Index");
}

问题是您正在使用声明来存储数据。声明或更具体的标识声明应该对标识进行建模。将声明视为生日、驾驶执照号码、性别。不经常更改的声明。

因此,解决方案是从声明中删除数据并将其移动到存储中。它可能是业务上下文的一部分。

Q1: 选择可以保存在 Cookie 中。将(业务(上下文中的选择保存为备用,以防 Cookie 被删除。

问题 2:声明不会保留在数据库中。它只创建一个 ClaimIdentity。声明存储在令牌或 Cookie 中,具体取决于方案。

最新更新