4

When I wrote my asp.net core authentication, it did not require the "Remember Me" functionality and this is how I implemented my auth (sliding expiration of 30 mins):

Startup.cs

var roleStore = new CustomRoleStore();
var userPrincipalFactory = new CustomUserPrincipalFactory();

services.AddSingleton<IRoleStore<ApplicationRole>>(roleStore);
services.AddSingleton<IUserClaimsPrincipalFactory<ApplicationUser>>(userPrincipalFactory);

services.AddIdentity<ApplicationUser, ApplicationRole>(options => {
    options.Cookies.ApplicationCookie.ExpireTimeSpan = 30;
    options.Cookies.ApplicationCookie.SlidingExpiration = true;
}).AddDefaultTokenProviders();

AccountController.cs

[HttpPost("Login")]
[AllowAnonymous]
public async Task<IActionResult> Login(UserLogin model)
{
    // If the model is valid, then attempt a login.
    if (ModelState.IsValid)
    {
        try
        {
            // Wait for the result for sign in.
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);

            // If the call was successful, then update the last sign in.
            if (result.Succeeded)
                return Json(new { success = true, errorcode = 0, result = true });
        }
        catch (Exception ex)
        {
             return Json(new { success = false, errorcode = 115 });            
        }
    }

    // Return bad request response.
    return BadRequest(new { success = false, errorcode = 111 });
}

Other note, I've implemented my own custom user store and role store, who's signatures look as follows:

CustomUserStore class

public class CustomUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>, IUserLoginStore<ApplicationUser>, IUserLockoutStore<ApplicationUser>,  IUserPhoneNumberStore<ApplicationUser>, IUserTwoFactorStore<ApplicationUser> 

CustomRoleStore class

public class CustomRoleStore : IRoleStore<ApplicationRole>

I now have the need to implement the remember me functionality, and by changing the one option you'd expect to work (param to PasswordSignInAsync - IsPersistent was always false, now it can be true), my requests still return authenticated along with a auth cookie but subsequent requests return 401 as they cant pick up the auth cookie? (HttpContext.User.Identity.IsAuthenticated is false). I've seen articles such as this:

How do I forcefully propagate role changes to users with ASP.NET Identity 2.0.1?

But they seem to do their authenticate in a slightly different way than I have (I've implemented my own middleware to handle authentication):

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(15),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)),
    },
    SlidingExpiration = false,
    ExpireTimeSpan = TimeSpan.FromMinutes(30)
});

Can anyone suggest how to get the persistent cookie working? Can I swap out my code (at the top) for this code (just above)? The only difference from this working to not working is the one param IsPersistent changing from always false to sometimes true now.

Please help and thanks in advance for any pointers!

Community
  • 1
  • 1
Rob
  • 6,819
  • 17
  • 71
  • 131

0 Answers0