2

This seems like a pretty stupid question, but I'm trying to figure out the best way to do this. Would you simply redirect to a /Logout page and have the controller call the FormsAuthentication.SignOut function?

That was my first thought, but then I wondered if it could be abused by third party websites. Let's say someone just decides to post a link to your /Logout page. The user would get signed out of your application. Is there a good way to prevent that?

Gulzar Nazim
  • 51,744
  • 26
  • 128
  • 170
Kevin Pang
  • 41,172
  • 38
  • 121
  • 173

7 Answers7

5

If you are concerned about a user getting accidentally logged out of you application through the use of a malicious link, you can check the Referrer to make sure that the logout is coming from your site (or is NULL in the case where the user simply types the URL in).

I actually don't worry about this since logging someone out is annoying but not necessarily a security risk.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • My thoughts as well. While annoying, it's not a security risk. – Michael Brown Oct 21 '08 at 00:40
  • I agree, I don't think maliciously logging people out is a big problem. And they would have had to had left your site anyway to go to the other site so having to log back in when they return shouldn't be a problem. – Craig Oct 21 '08 at 00:58
  • Referrers can be spoofed way to easily. Check the CSRF answer. – Chuck Aug 21 '09 at 19:42
  • My last point was that while annoying it's not particularly egregious. I regard a spoofed Referer in this case to be innocuous and wouldn't put much effort into verifying that the logout is coming from the correct host. It goes without saying that it should be a GET request and not be allowed to modify any data directly. – tvanfosson Aug 21 '09 at 19:47
5

Such a malicious link would be an example of a class of security vulnerabilities known as cross site request forgery, CSRF. A logout link is relatively harmless, but a remote site could set up a number of hidden forms and post them to your site to perform any action possible through POST.

The most common counter-measure is to include a challenge, a random hidden value in each form, and then check for that value. Checking the referer header could work, but note that some browsers don't send referer at all.

Read more: http://en.wikipedia.org/wiki/Cross-site_request_forgery

jakber
  • 3,549
  • 20
  • 20
3

This is what I use.

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

Seems to work fine.

Third party websites are only going to log themselves out. So they wouldn't be achieving anything different from actually clicking Logout.

Schotime
  • 15,707
  • 10
  • 46
  • 75
  • So let's say your app is located at http://url.com and your logout page is http://url.com/logout. If a third party website posted a link to http://url.com/logout, any users that are logged into your app that click that link will log themselves out, right? – Kevin Pang Oct 21 '08 at 00:27
  • Can you check to see if it is a postback in MVC? if so, then logout, otherwise just redirect to the index view? – Mark Oct 21 '08 at 00:30
  • @kevin, Only the 3rd party app would be logged out. No users currently using your application would be logged out until they clicked it themselves. @Mark You could allow only GET requests to the controller. – Schotime Oct 21 '08 at 03:10
  • what if the rest of your site is using older aspx stuff and you're trying to implement an MVC login/logout interface on top of that? Right now, my login page MVC project doesn't have an index or home view. The home page of the site is an aspx page in another non-MVC project, so when the user logs out i want to redirect to the login view with a return URL on it to take them to the home.aspx of another project once they log back in. right now i'm trying FormsAuth.SignOut then return RedirectToAction("LogOn", "Account"); but if the user tries to login again, it just keeps them at the login view – topwik Nov 16 '11 at 14:47
  • ok, to answer my query, you just redirect to your main aspx page after you logout so it forces the LogOn View complete with the proper return URL. Like so public ActionResult LogOff() { FormsAuthentication.SignOut(); return Redirect("/localhost/Home.aspx"); } Word! – topwik Nov 16 '11 at 15:03
  • good answer. For clarity its -> FormsAuthentication.SignOut(); – JGilmartin Feb 21 '15 at 10:37
3

This is an old question, but here is a modern example with MVC:

[Authorize]
public RedirectResult Logout()
{
    FormsAuthentication.SignOut();

    return this.Redirect("/");
}

You can ensure that the Logout action is only able to be called by somebody who is logged in by applying the Authorize attribute to it.

rhughes
  • 9,257
  • 11
  • 59
  • 87
2

The new ASP.net MVC Beta contains an AccountController, which may be worth looking at, as it essentially implements everything from Registration to Login/Logout to Forgot Password functionality. Not sure how good it is, but a good starting Point for sure.

Michael Stum
  • 177,530
  • 117
  • 400
  • 535
  • BTW, Mike, congrats on being the first CrackOverflow addict to break 10k. –  Oct 21 '08 at 01:20
1

Derive from ActionResult

public class LogoutResult : ActionResult
{
    private readonly IAuthenticationService _authenticationService;
    private readonly IWebContext _context;

    public LogoutResult(IAuthenticationService authenticationService, IWebContext context)
    {
        _authenticationService = authenticationService;
        _context = context;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        _authenticationService.Logout();
        _context.Abandon();
        _context.Redirect("~/");
    }
}
Matt Hinze
  • 13,577
  • 3
  • 35
  • 40
0

You should look for a cookie or something that identifies the client as the true user.

SaaS Developer
  • 9,835
  • 7
  • 34
  • 45
  • How would that help? The user would still be logged out when they clicked the link. – Kevin Pang Oct 21 '08 at 00:22
  • Doesn't this problem exist with any web application, built with any language, where logging out involves going to some kind of logout page? You could check the referrer and make sure that the user came from the same domain, but that's not always reliable. – Mun Oct 21 '08 at 00:27