Perpetual expiry of claims in SignInWithClaimsAsync

Viewed 449

I am using ASP.NET Core 3.1 with Identity and storing some basic user information like their full name in a claim using the code below (I am aware of checking password and stuff, ignoring it for brevity):

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

I am accessing it in the _Layout.cshtml using the line below:

var userFullname = User.Claims.Single(c => c.Type == "UserFullname").Value;

The problem is, this seems to expire in some time even though the user is still logged in. I want this to be perpetual until the user logs out.

I am sure there has to be some way in startup.cs to control this and as far as possible, I would like to avoid overriding anything.

--EDIT--
As mentioned in the comments for answer by @yinqiu, I tried the cookie authentication scheme using the line below:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);

But it did not help either.

2 Answers

I think you can try to override the SignInWithClaimsAsync method.

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

This is the appropriate solution of your case: If you are inheriting Identity Classes (IdentityRole,IdentityUser) into your custom classes then you need to use your inherited classes otherwise you use the default Identity Classes. You need a custom ClaimIdentity Class let assume 'ApplicationClaimsIdentityFactory' and this class should be inherited by UserClaimsPrincipalFactory<AspNetUser, AspNetRole>

Step1 Register your dependencies in Startup.cs

services.AddIdentity<AspNetUser, AspNetRole>().AddEntityFrameworkStores<ICRCOMDMSEntities>().AddDefaultTokenProviders();
services.AddScoped<IUserClaimsPrincipalFactory<AspNetUser>, ApplicationClaimsIdentityFactory>();

Step2: Override the method CreateAsync in your custom claimsIdentityFactory Calss and here you need to create your custom claims and return like

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

Now your claims persists until user is logged in.

Related