Search code examples
c#asp.netasp.net-membershipasp.net-4.5

User.Identity.IsAuthenticated is false after successful login


I need to get the UserId Guid directly after a successful login. The following code doesn't work:

if (Membership.ValidateUser(txtUsername.Value, txtPassword.Value))
{
    FormsAuthentication.SignOut();
    FormsAuthentication.SetAuthCookie(txtUsername.Value, true);

    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        // doesn't run
        Guid puk = (Guid)Membership.GetUser().ProviderUserKey;            
    }
}

The following code does work:

if (Membership.ValidateUser(txtUsername.Value, txtPassword.Value))
{
    FormsAuthentication.SignOut();
    FormsAuthentication.SetAuthCookie(txtUsername.Value, true);

    MembershipUser user = Membership.GetUser(txtUsername.Value);

    if (user != null)
    {
        Guid puk = (Guid)user.ProviderUserKey;
    }
}

Why does this happen? Is there something more to do besides SetAuthCookie?


Solution

  • Because when you call FormsAuthentication.SetAuthCookie(txtUsername.Value, true); you store the key on the client's cookies. For this you need to do a response to the user. And for HttpContext.Current.User.Identity to be filled with cookie you need one more request.

    In short your scheme looks like this:

    1. Client sends his UserName and Password.

    2. Server gets and checks it. If they are valid the server sends Set-Cookie header to the client.

    3. Client receives and stores it. For each request client sends cookies back to the server.

    UPDATE for @Jake

    Adding an example of setting User in HttpContext

    var identity = new System.Security.Principal.GenericIdentity(user.UserName);
    var principal = new GenericPrincipal(identity, new string[0]);
    HttpContext.Current.User = principal;
    Thread.CurrentPrincipal = principal;  
    

    Note that you could create your custom principal class inheriting from GenericPrincipal or ClaimsPrincipal