5

I have ASP.NET MVC 5.0 project using ASP.NET Identity. When user log in i use this function to track user by system.

SignInManager.SignIn(user,IsPersistent,false)

In user profile i have ability to change UserName, after that i need automatically to relogin user to stay user tracking. I logout user and use this function to login, but where i can get IsPersistent property of current session?

I can store IsPersistent in User table on database after each login, but I think this is not the best solution.

Dmitrij Polyanin
  • 485
  • 5
  • 23

2 Answers2

1

I have changed the Login code in AccountController's Login action to meet your requirements. I have commented out ASP.NET Identity default login mechanism.

Now what this code will do is that it will first find the user and then check if the entered password matches with the user's password. Once the password is matched, it would add a fake claim to the user to store the persistent state and sign in the user.

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    SignInStatus result = SignInStatus.Failure;

    var user = UserManager.FindByEmail(model.Email);
    if (user != null)
    {
        var isPasswordOk = UserManager.CheckPassword(user, model.Password);
        if (isPasswordOk)
        {
            user.Claims.Add(new IdentityUserClaim() { ClaimType = "IsPersistent", ClaimValue = model.RememberMe.ToString() });
            await SignInManager.SignInAsync(user, model.RememberMe, false);

            result = SignInStatus.Success;
        }
    }

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, change to shouldLockout: true
    //var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);

    switch (result)
    {
        case SignInStatus.Success:
            return RedirectToLocal(returnUrl);

        case SignInStatus.LockedOut:
            return View("Lockout");

        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });

        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return View(model);
    }
}

Once the user is logged in through, you can check if a user is persistent using below code.

if (User.Identity.IsAuthenticated)
{
    Claim claim = ((ClaimsIdentity)User.Identity).FindFirst("IsPersistent");
    bool IsPersistent = claim != null ? Convert.ToBoolean(claim.Value) : false;
}

I hope this solves your problem.

  • 1
    But if this information is in claims how it will work on different divices. If on one computer i make permanent login and on other temporary? – Dmitrij Polyanin Jun 23 '18 at 09:43
  • @DmitrijPolyanin I couldn’t get your question. A separate session is generated for every login on a different device/browser so logging into one device/browser with permanent login will keep the login permanent and logging on a different device with a temporary login will expire the session as you close the browser. – Mohammad Ajmal Amirzad Jun 23 '18 at 16:10
  • I am not arguing, but trying to understand – Dmitrij Polyanin Jun 23 '18 at 19:50
  • I stored it in Claims instead of session because i wanted this to be available for the whole life of the login period. – Mohammad Ajmal Amirzad Jun 24 '18 at 04:59
0

To get the value of IsPersistent, call AuthenticateAsync:

@using Microsoft.AspNet.Identity;

var authenticateResult = await HttpContext.GetOwinContext()
                               .Authentication.AuthenticateAsync(
                                   DefaultAuthenticationTypes.ApplicationCookie
                               );
var isPersistent = authenticateResult.Properties.IsPersistent; //// true or false
Alfred Wallace
  • 1,741
  • 1
  • 14
  • 32