FormsAuthentication.SignOut() does not log the use

2019-01-01 02:58发布

Smashed my head against this a bit too long. How do I prevent a user from browsing a site's pages after they have been logged out using FormsAuthentication.SignOut? I would expect this to do it:

FormsAuthentication.SignOut();
Session.Abandon();
FormsAuthentication.RedirectToLoginPage();

But it doesn't. If I type in a URL directly, I can still browse to the page. I haven't used roll-your-own security in a while so I forget why this doesn't work.

23条回答
孤独寂梦人
2楼-- · 2019-01-01 03:17

I've struggled with this before too.

Here's an analogy for what seems to be going on... A new visitor, Joe, comes to the site and logs in via the login page using FormsAuthentication. ASP.NET generates a new identity for Joe, and gives him a cookie. That cookie is like the key to the house, and as long as Joe returns with that key, he can open the lock. Each visitor is given a new key and a new lock to use.

When FormsAuthentication.SignOut() is called, the system tells Joe to lose the key. Normally, this works, since Joe no longer has the key, he cannot get in.

However, if Joe ever comes back, and does have that lost key, he is let back in!

From what I can tell, there is no way to tell ASP.NET to change the lock on the door!

The way I can live with this is to remember Joe's name in a Session variable. When he logs out, I abandon the Session so I don't have his name anymore. Later, to check if he is allowed in, I simply compare his Identity.Name to what the current session has, and if they don't match, he is not a valid visitor.

In short, for a web site, do NOT rely on User.Identity.IsAuthenticated without also checking your Session variables!

查看更多
伤终究还是伤i
3楼-- · 2019-01-01 03:20

This works for me

public virtual ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        foreach (var cookie in Request.Cookies.AllKeys)
        {
            Request.Cookies.Remove(cookie);
        }
        foreach (var cookie in Response.Cookies.AllKeys)
        {
            Response.Cookies.Remove(cookie);
        }
        return RedirectToAction(MVC.Home.Index());
    }
查看更多
不流泪的眼
4楼-- · 2019-01-01 03:20

I just tried some of the suggestions here and while I was able to use the browser back button, when I clicked on a menu selection the [Authorize] token for that [ActionResult] sent me right back to the login screen.

Here is my logout code:

        FormsAuthentication.SignOut();
        Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
        HttpCookie cookie = HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (cookie != null)
        {
            cookie.Expires = DateTime.Now.AddDays(-1);
            Response.Cookies.Add(cookie);
        }

Although the back function on the browser took me back and displayed the secured menu (I am still working on that) I was not able to do anything that was secured in the app.

Hope this helps

查看更多
余生无你
5楼-- · 2019-01-01 03:21

Just try to send a session variable when you press log in. And on the welcome page, first check whether that session is empty like this in the page load or in the Init Event:

if(Session["UserID"] == null || Session["UserID"] == "")
{
    Response.Redirect("Login.aspx");
}
查看更多
美炸的是我
6楼-- · 2019-01-01 03:22

Be aware that WIF refuses to tell the browser to cleanup the cookies if the wsignoutcleanup message from STS doesn't match the url with the name of the application from IIS, and I mean CASE SENSITIVE. WIF responds with the green OK check, but will not send the command to delete cookies to browser.

So, you need to pay attention to the case sensitivity of your url's.

For example, ThinkTecture Identity Server saves the urls of the visiting RPs in one cookie, but it makes all of them lower case. WIF will receive the wsignoutcleanup message in lower case and will compare it with the application name in IIS. If it doesn't match, it deletes no cookies, but will report OK to the browser. So, for this Identity Server I needed to write all urls in web.config and all application names in IIS in lower case, in order to avoid such problems.

Also don't forget to allow third party cookies in the browser if you have the applications outside of the subdomain of STS, otherwise the browser will not delete the cookies even if WIF tells him so.

查看更多
时光乱了年华
7楼-- · 2019-01-01 03:23

For me, the following approach works. I think if there is any error after the "FormsAuthentication.SignOut()" statement, SingOut doesn't work.

public ActionResult SignOut()
    {
        if (Request.IsAuthenticated)
        {
            FormsAuthentication.SignOut();

            return Redirect("~/");
        }
        return View();
     }
查看更多
登录 后发表回答