我正在使用带有Identity的ASP.NET Core 3.1,并使用下面的代码将一些基本用户信息(如他们的全名(存储在声明中(我知道会检查密码和其他内容,为了简洁起见会忽略它(:
var user = await _userManager.FindByNameAsync(Input.Username);
var claims = new List<Claim>
{
new Claim("UserFullname", user.Fullname, ClaimValueTypes.String)
}
await _signInManager.SignInWithClaimsAsync(user, Input.RememberMe, claims);
我正在_Layout.cshtml
中使用以下行访问它:
var userFullname = User.Claims.Single(c => c.Type == "UserFullname").Value;
问题是,即使用户仍然登录,它似乎也会在一段时间内过期。我希望在用户注销之前,它是永久的。
我相信startup.cs
中必须有某种方法来控制这一点,并且尽可能避免覆盖任何内容。
--EDIT-
正如@yinqiu在回复评论中提到的,我使用以下行尝试了cookie身份验证方案:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
但这也无济于事。
这是您的案例的适当解决方案:如果要将标识类(IdentityRole、IdentityUser(继承到自定义类中,则需要使用继承的类,否则使用默认的标识类。您需要一个自定义ClaimIdentity类,假设为"ApplicationClaimsIdentity Factory",并且该类应由UserClaimsPrincipalFactory继承<AspNetUser,AspNetRole>
Step1在Startup.cs 中注册您的依赖项
services.AddIdentity<AspNetUser, AspNetRole>().AddEntityFrameworkStores<ICRCOMDMSEntities>().AddDefaultTokenProviders();
services.AddScoped<IUserClaimsPrincipalFactory<AspNetUser>, ApplicationClaimsIdentityFactory>();
第2步:在您的自定义索赔中重写方法CreateAsync Identity Factory Calss,在这里您需要创建自定义索赔并像一样返回
public async override Task<ClaimsPrincipal> CreateAsync(AspNetUser user)
{
var principal = await base.CreateAsync(user);
((ClaimsIdentity)principal.Identity).AddClaims(new[] {
new Claim("UserLastLogin", user.LastLoginDate.ToString("dd/MM/yyyy hh:mm:ss tt"))
});
return principal;
}
现在,您的索赔将一直持续到用户登录为止。
我认为您可以尝试覆盖SignInWithClaimsAsync
方法。
public override async Task SignInWithClaimsAsync(ApplicationUser user, AuthenticationProperties authenticationProperties, System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> additionalClaims)
{
if (authenticationProperties != null && authenticationProperties.IsPersistent)
{
authenticationProperties.ExpiresUtc = DateTimeOffset.UtcNow.AddYears(1);
}
await base.SignInWithClaimsAsync(user, authenticationProperties, additionalClaims);
}