ASP.NET MVC 3 HttpContext.Current.User.Identity.IsAuthenticated is always false

3.8k Views Asked by At

I have two controllers, AdminController and AccountController with the following code

AccountController:

[HttpPost]
    public ActionResult LogOn(LogOnViewModel model)
    {
        if (ModelState.IsValid)
        {
            _authenticationService.SetPrincipal(model.UserName);
            var exists = _authenticationService.ValidateCredentials(userName, password);
            FormsAuthentication.SetAuthCookie(model.UserName, false);
            if(exists){
                 return RedirectToAction("Index", "Admin");

            }
        }

        return RedirectToAction("LogOn");
    }

AdminController:

[Authenticate]
public class AdminController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }
}

AuthenticateAttribute is inherited from AuthorizeAttribute and has the following code:

protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authenticated = false;
        if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)
        {
            //some actions
        }
        else
        {
            FormsAuthentication.SignOut();
            FormsAuthentication.RedirectToLoginPage();
        }

        return authenticated;
    }

_authenticationService is the instance of AuthenticationService class and SetPrincipal() method has the following code:

public void SetPrincipal(string userName)
    {
        var identity = new GenericIdentity(userName);
        var principal = new GenericPrincipal(identity, null);
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            var ticket = new FormsAuthenticationTicket(1,
                principal.Identity.Name,
                DateTime.Now,
                DateTime.Now.AddMinutes(30),
                false,
                String.Empty,
                FormsAuthentication.FormsCookiePath);

            string encryptedCookie = FormsAuthentication.Encrypt(ticket);
            var authenticationCookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName];
            if (authenticationCookie != null)
            {
                authenticationCookie.Value = encryptedCookie;
                authenticationCookie.Expires = DateTime.Now.AddMinutes(30);
            }
            HttpContext.Current.User = principal;
        }
    }

When I debug and watch AuthenticationService.SetPrincipal() HttpContext.Current.User.Identity.IsAuthenticated is true. But after redirect to Index action of AdminController in AuthenticateAttribute.AuthorizeAttribute() HttpContext.Current.User.Identity.IsAuthenticated is always false. As result I redirected to LogOn view again. What am I doing wrong?

1

There are 1 best solutions below

6
On

I don't see anywhere where you actually send the cookie back to the client. In order to be authenticated on each subsequent request, you have to send the encrypted cookie back to the client so that it can pass it back to your site.

HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie);
Response.Cookies.Add(cookie);

I see where you try and get the current authentication cookie here:

var authenticationCookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName];

But again, this is a GET, not a SET (or sending the cookie back) function line. At this point in your authentication, if you set a debugger, authenticationCookie is always going to be NULL.

Also, I don't see where you validate the password in any of your actions or functions. Ensure you are not overlooking that step.

One more thought/question/issue with your code. You are setting a variable called userExists in your controller action, but the function you call is a void type, so...you don't need to set that variable, just call the function.

_authenticationService.SetPrincipal(model.UserName);
return RedirectToAction("Index", "Admin");