3

I'm using the basic mvc-5 login method and just trying to access the userid on success

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

    // 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:
            string userId = User.Identity.GetUserId();
            returnUrl = CheckUserRoleAndRedirect();
            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);
    }
}

Here string userId = User.Identity.GetUserId(); userId return null for the 1st time but next time it works fine

2 Answers 2

7

After logging in (and redirecting to another page), the IPrincipal.IIdentity should be a ClaimsIdentity. You can try this:

var claimsIdentity = User.Identity as ClaimsIdentity;
if (claimsIdentity != null)
{
    // the principal identity is a claims identity.
    // now we need to find the NameIdentifier claim
    var userIdClaim = claimsIdentity.Claims
        .FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);

    if (userIdClaim != null)
    {
        var userIdValue = userIdClaim.Value;
    }
}

This should work for you. If you still unable to get the id then you have to redirect to another page before the server will write the authentication cookie to the browser.

Or Another approach is this :

switch (result)
{
    case SignInStatus.Success:
       ApplicationUser user = UserManager.FindByName(model.UserName);
       string UserId = user.Id;
       returnUrl = CheckUserRoleAndRedirect();
       return RedirectToLocal(returnUrl);
}
Sign up to request clarification or add additional context in comments.

3 Comments

is there a way to use identity to get userid before redirection?
string userId = User.Identity.GetUserId(); is something wrong in this?
No. This is perfectly fine but you will get id after redirecting only
6

Once called, SignInAsync creates a AuthenticationResponseGrant and details are not available in User.Identity until next call.

However you can get around this by accessing AuthenticationResponseGrant.Identity directly:

var Grant = SignInManager.AuthenticationManager.AuthenticationResponseGrant;
string UserId = Grant.Identity.GetUserId();

Of course there is no need to map Grant however it makes the code more readable.

1 Comment

This is fantastic. Reliably allows you to access the ClaimsIdentity before redirect occurs. Nice one!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.