4

I am trying to implement Logout Functionality in ASP.NET MVC.

I use Forms Authentication for my project.

This is my Logout code:

FormsAuthentication.SignOut();
Response.Cookies.Clear();
FormsAuthenticationTicket ticket = 
    new FormsAuthenticationTicket(
        1,
        FormsAuthentication.FormsCookieName,
        DateTime.Today.AddYears(-1),
        DateTime.Today.AddYears(-2),
        true,
        string.Empty);

Response.Cookies[FormsAuthentication.FormsCookieName].Value = 
            FormsAuthentication.Encrypt(ticket); 
Response.Cookies[FormsAuthentication.FormsCookieName].Expires = 
            DateTime.Today.AddYears(-2);

return Redirect("LogOn");

This code redirects the user to the Login Screen. However, if I call an action method by specifying the name in address bar (or select the previous link from address bar dropdown), I am still able to reach the secure pages without logging in.

Could someone help me solve the issue?

Venemo
  • 18,515
  • 13
  • 84
  • 125
vijaysylvester
  • 4,750
  • 7
  • 29
  • 41
  • Why are u not using FormsAuthentication.SignOut() ? – Aliostad Oct 08 '10 at 09:55
  • @Aliostad : Now changed the source code , previously the method call was wrapped. – vijaysylvester Oct 08 '10 at 10:04
  • @vijaysylvester - Could you please give us some details about how you actually make your secure pages secure? – Venemo Oct 08 '10 at 10:20
  • I have configured them in Web.Config to deny access for users not authenticated. – vijaysylvester Oct 08 '10 at 10:28
  • @vijaysylver - there's your problem. This is not web forms, this is MVC. Venemo's answer is spot on - you need to decorate the action methods with authorize. I bet even if you didnt log in, you could get to any secure page. – RPM1984 Oct 08 '10 at 10:30
  • @vijaysylver - As I said in my answer, that no longer works with MVC. Use the `AuthorizeAttribute` instead. – Venemo Oct 08 '10 at 10:36
  • @Venemo : Yes .I am Trying that – vijaysylvester Oct 08 '10 at 10:39
  • @RPM1984 : If your take is true , then when you create a new ASP.NET MVC application from visual studio , it uses FormsAuthentication , It does not have Authenticate attribute on top of actions. Yet it prevents un authenticated users . Did you notice that ? – vijaysylvester Oct 08 '10 at 11:04
  • @vijaysylver - what are you talking about? When you create a new ASP.NET MVC 2 Web Appliaction from VS 2010, there are only 3 pages - Home, About, Login. `None` of these pages prevent un-authenticated users. The only page that does is if you go to `http://localhost:{port}/account/changepassword` (hidden page), it redirects you to the login page. This is because if you look at the AccountController ChangePassword action methods, they are decorated with `[Authorize]`. – RPM1984 Oct 10 '10 at 22:51

4 Answers4

6

That's strange... I make one single call to: FormsAuthentication.SignOut(); and it works...

public ActionResult Logout() {
  FormsAuthentication.SignOut();
  return Redirect("~/");
}
Palantir
  • 23,820
  • 10
  • 76
  • 86
  • I used reflector and saw what the FormsAuth.SignOut() was doing. It does the same thing i am trying to accomplish. that is setting the cookie's expires property to the previous date. But it carefully adds the cookie to the response , but i dint do that , that is the issue here. Thanks for the help! – vijaysylvester Oct 15 '10 at 01:33
1

To correctly answer your question, I'd have to know how do you secure your "secure" pages.
I suspect that you're doing something wrong there.

A simple call to FormsAuthentication.SignOut() should be enough, as it clears the authentication cookie, thus making the other method calls you make there redundant.

With ASP.NET MVC, you have to use the AuthorizeAttribute on an action method to disallow non-authenticated visitors to use it. (Meaning: the old way you did it with Web Forms by specifying location tags in Web.config no longer works with MVC.)

For example, here is a small code snippet from my ForumController class:

public class ForumController : Controller
{
    ...

    [Authorize]
    public ActionResult CreateReply(int topicId)
    {
        ...
    }

    ...
}
Venemo
  • 18,515
  • 13
  • 84
  • 125
  • To be clear , Even if you clear the cookie at server side using SignOut(), The Client passes the Forms Auth Cookie at the next request. To prevent this i am adding a cookie with same name , but with an expired time. – vijaysylvester Oct 08 '10 at 10:08
  • @vijaysylvester - Well then, how do you explain that it works for me and @Palantir too? – Venemo Oct 08 '10 at 10:19
  • @vijaysylvester - you are correct that the cookie will still be sent (until it is expired), but it wont matter, as this cookie will be seen as 'stale' to ASP.NET. There are other steps to bolster this, such as absolute expiration and SSL - but the 'hack' of adding a cookie with the same name is not one of them. I dont think FormsAuth is the problem here. – RPM1984 Oct 08 '10 at 10:24
  • @Venemo: Cheers mate! You both were successful in the 1st line that is FormsAuthentication.SignOut() , Since i was not , i tried other options as well. As simple as that. – vijaysylvester Oct 08 '10 at 10:25
  • Im confused, are you saying you `didnt` have FormsAuthentication.SignOut() in your original code? Then why is it in the question? – RPM1984 Oct 08 '10 at 10:29
  • @RPM1984 : To be clear , i dint achieve what i intended to do using FormsAuthentication.SignOut() method, so i went on with adding expired cookie with same name hence forth. – vijaysylvester Oct 08 '10 at 10:34
  • @vijaysylver - that's actually not clear at all. What do you mean you "didnt achieve what you intended". FormsAuthentication.Signout() is intended to signout (aka logout) a authenticated user from a website. What else do you "intend" it to do? – RPM1984 Oct 08 '10 at 10:40
  • @RPM1984 : I intended to logout , the method didnot facilitate that, so was trying with other options. – vijaysylvester Oct 08 '10 at 11:06
1

The following question is related the it's solution works for me

FormsAuthentication.SignOut() does not log the user out

Community
  • 1
  • 1
Phil Hale
  • 3,453
  • 2
  • 36
  • 50
0

This method works, if you do not disable[comment] the following tags in the web.config file to test your web application easily.

public ActionResult SignOut()
{
    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}

web.config

<authentication mode="Forms">
  <forms name="Your Project Name" defaultUrl="/" loginUrl="/Users/Login" timeout="43200" />
</authentication>

<location path="Administrator">
  <system.web>
    <authorization>
      <allow roles="Administrator" />
      <deny users="*" />
    </authorization>
  </system.web>
</location>

<location path="UserPanel">
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
</location>
Jahed Kabiri
  • 115
  • 5