62

I have a page that when you press 'log out' it will redirect to the login.aspx page which has a Page_Load method which calls FormsAuthentication.SignOut().

The master page displays the 'log out' link in the top right of the screen and it displays it on the condition that Page.User.Identity.IsAuthenticated is true. After stepping through the code however, this signout method doesn't automatically set IsAuthenticated to false which is quite annoying, any ideas?

Mitat Koyuncu
  • 868
  • 8
  • 19
lisburnite
  • 2,270
  • 5
  • 28
  • 56
  • My understanding is that you should check auth cookie presence, rather than this flag? – Sheen Oct 29 '10 at 10:27
  • 1
    And how do I do this? I think the cookie still exists after FormsAuthentication.SignOut(). – lisburnite Oct 29 '10 at 10:38
  • possible duplicate question http://stackoverflow.com/questions/412300/formsauthentication-signout-does-not-log-the-user-out – BrokenGlass Oct 29 '10 at 12:50
  • 2
    Remember that: Authenticated = "System know who you are" Authorized = "System know what you are allowed to do". That said: LogOut = "Authorized to nothing" .... but "System still knows who you are" – Kasper Halvas Jensen Apr 14 '16 at 11:15

7 Answers7

107

Page.User.Identity.IsAuthenticated gets its value from Page.User (obviously) which is unfortunately read-only and is not updated when you call FormsAuthentication.SignOut().

Luckily Page.User pulls its value from Context.User which can be modified:

// HttpContext.Current.User.Identity.IsAuthenticated == true;

FormsAuthentication.SignOut();
HttpContext.Current.User =
    new GenericPrincipal(new GenericIdentity(string.Empty), null);

// now HttpContext.Current.User.Identity.IsAuthenticated == false
// and Page.User.Identity.IsAuthenticated == false

This is useful when you sign out the current user and wish to respond with the actual page without doing a redirect. You can check IsAuthenticated where you need it within the same page request.

Mart
  • 5,010
  • 3
  • 30
  • 43
13

A person is only authenticated once per request. Once ASP.NET determines if they are authenticated or not, then it does not change for the remainder of that request.

For example, when someone logs in. When you set the forms auth cookie indicating that they are logged in, if you check to see if they are authenticated on that same request, it will return false, but on the next request, it will return true. The same is happening when you log someone out. They are still authenticated for the duration of that request, but on the next one, they will no longer be authenticated. So if a user clicks a link to log out, you should log them out then issue a redirect to the login page.

Brian Ball
  • 11,134
  • 1
  • 35
  • 48
6

I remember having a similar problem and I think I resolved it by expiring the forms authentication cookie at logout time:

FormsAuthentication.SignOut();
Response.Cookies[FormsAuthentication.FormsCookieName].Expires = DateTime.Now.AddYears(-1);
PatrickSteele
  • 13,475
  • 2
  • 44
  • 52
4

Why are you executing logout code in the login.aspx?

Put this code in e.g. logout.aspx:

FormsAuthentication.SignOut()
Session.Abandon()
FormsAuthentication.RedirectToLoginPage()
HttpContext.Current.ApplicationInstance.CompleteRequest()
return

IsAuthenticated will be false in login.aspx. Login and logout code are now separated: Single Responsibility.

Michel van Engelen
  • 2,621
  • 1
  • 23
  • 42
1

In one of my application when I am signIn with credentials , navigating to different forms in an application then i have copied one of my navigated form url then logout form the application. in the search tab i have paste the url the browser is navigating to the specific form in my application without login. while checking the form authentication as page.User.Identity.IsAuthenticated getting as true even when we logout.The causes for this is while clearing the session on logout i have added

Response.Cookies[FormsAuthentication.FormsCookieName].Expires = DateTime.Now.AddYears(-1);

with this I am not getting that issue again and the flag page.User.Identity.IsAuthenticated getting as false when we are navigating to the different forms in an application without login.

deHaar
  • 11,298
  • 10
  • 32
  • 38
Mike
  • 11
  • 1
1

In your login.aspx Page_Load method:

if (!this.IsPostBack)
{
    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        FormsAuthentication.SignOut();
        Response.Redirect(Request.RawUrl);
    }
}
James McCormack
  • 8,920
  • 3
  • 45
  • 55
0

Update

I got comments that my answer didn't work with many folks. I wrote this answer back in 2011 after tearing my hear. So I am pretty sure it solved the problem.

I started to research this 6 years old problem and came to this solution which I believe might be the proper way of deleting the cookies which is by creating them again but with expired dates.


This works for me

public virtual ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        foreach (var cookie in Response.Cookies.AllKeys)
        {
            Response.Cookies.Remove(cookie);
        }
        return RedirectToAction(MVC.Home.Index());
    }
Community
  • 1
  • 1
Korayem
  • 10,709
  • 5
  • 65
  • 52
  • 1
    Removing a cookie on response will _not_ cause it to be deleted. Cookies need to expire, that's the only way to delete ones that are already set. – Sergey Jan 22 '16 at 22:46
  • Also you would not want to "expire" all cookies only the auth cookies – Mike Dec 07 '17 at 19:50
  • @Mike how about this solution https://stackoverflow.com/a/24961207/80434? – Korayem Dec 11 '17 at 15:18
  • Yes that example works because the person goes through all the cookies on the *response* and changes them to be already expired, then those expired cookies are sent in the response and when the client browser receives them, it automatically deletes them because they're expired. The `HttpContext.Current.Request.Cookies.Clear();` line is modifying the current *request* object, not the response - that means that as the code continues processing that request, there are no cookies for it to work with. The response however *still* contains all the cookies, but expired. – Sergey Feb 15 '18 at 18:00
  • Your example does _nothing_ to change the expiration of the cookies. ...I do have to admit that I'm not sure if `HttpOnly` cookies have to be deleted that way. It's possible that all they need is to be removed. – Sergey Feb 15 '18 at 18:03