【问题标题】:How do you implement a "Logout" link using ASP.NET MVC?如何使用 ASP.NET MVC 实现“注销”链接?
【发布时间】:2010-09-18 05:40:12
【问题描述】:

这似乎是一个非常愚蠢的问题,但我正在尝试找出最好的方法来做到这一点。您是否只需重定向到 /Logout 页面并让控制器调用 FormsAuthentication.SignOut 函数?

这是我的第一个想法,但后来我想知道它是否会被第三方网站滥用。假设某人刚刚决定发布指向您的 /Logout 页面的链接。用户将退出您的应用程序。有什么好的方法可以预防吗?

【问题讨论】:

    标签: asp.net-mvc forms-authentication


    【解决方案1】:

    您应该寻找一个 cookie 或将客户端识别为真正用户的东西。

    【讨论】:

    • 这有什么帮助?用户点击链接后仍会被注销。
    • 这种问题不存在于任何使用任何语言构建的 Web 应用程序中,其中注销涉及到某种注销页面吗?您可以检查引荐来源网址并确保用户来自同一个域,但这并不总是可靠的。
    【解决方案2】:

    这是我用的。

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

    似乎工作正常。

    第三方网站只会自行退出。因此,他们不会获得与实际单击注销不同的任何结果。

    【讨论】:

    • 假设您的应用位于url.com,而您的注销页面为url.com/logout。如果第三方网站发布了指向url.com/logout 的链接,那么任何登录到您的应用并单击该链接的用户都会将自己注销,对吗?
    • 你能检查一下它是否是 MVC 中的回发吗?如果是,则注销,否则只需重定向到索引视图?
    • @kevin,只有第 3 方应用程序会被注销。当前使用您的应用程序的用户不会被注销,直到他们自己单击它。 @Mark 您只能允许对控制器的 GET 请求。
    • 如果您的站点的其余部分使用较旧的 aspx 内容,并且您正尝试在此基础上实现 MVC 登录/注销界面,该怎么办?现在,我的登录页面 MVC 项目没有索引或主页视图。该站点的主页是另一个非 MVC 项目中的 aspx 页面,因此当用户注销时,我想重定向到带有返回 URL 的登录视图,一旦他们将他们带到另一个项目的 home.aspx重新登录。现在我正在尝试 FormsAuth.SignOut 然后返回 RedirectToAction("LogOn", "Account");但是如果用户尝试再次登录,它只会让他们在登录视图中
    • 好的,要回答我的问题,您只需在注销后重定向到您的主 aspx 页面,这样它就会强制使用正确的返回 URL 完成登录视图。像这样 public ActionResult LogOff() { FormsAuthentication.SignOut(); return Redirect("/localhost/Home.aspx"); } 字!
    【解决方案3】:

    如果您担心用户通过使用恶意链接意外退出您的应用程序,您可以检查引用者以确保退出来自您的站点(或者在用户只需输入 URL)。

    我实际上并不担心这一点,因为注销某人很烦人,但不一定有安全风险。

    【讨论】:

    • 我的想法也是如此。虽然很烦人,但这不是安全风险。
    • 我同意,我不认为恶意注销用户是一个大问题。而且他们无论如何都必须离开您的网站才能访问其他网站,因此当他们返回时必须重新登录应该不是问题。
    • 引荐来源网址很容易被欺骗。检查 CSRF 答案。
    • 我的最后一点是,虽然很烦人,但它并不是特别令人震惊。在这种情况下,我认为欺骗的 Referer 是无害的,并且不会花太多精力来验证注销是否来自正确的主机。不用说应该是GET请求,不允许直接修改任何数据。
    【解决方案4】:

    这样的恶意链接是一类被称为跨站请求伪造、CSRF 的安全漏洞的例子。注销链接相对无害,但远程站点可以设置许多隐藏表单并将它们发布到您的站点,以通过 POST 执行任何可能的操作。

    最常见的对策是在每个表单中包含一个挑战、一个随机隐藏值,然后检查该值。检查 referer 标头可以工作,但请注意,有些浏览器根本不发送 referer。

    阅读更多:http://en.wikipedia.org/wiki/Cross-site_request_forgery

    【讨论】:

      【解决方案5】:

      新的 ASP.net MVC Beta 包含一个 AccountController,可能值得一看,因为它基本上实现了从注册到登录/注销到忘记密码的所有功能。不确定它有多好,但肯定是一个很好的起点。

      【讨论】:

      • 顺便说一句,迈克,恭喜你成为第一个突破 10k 的 CrackOverflow 成瘾者。
      【解决方案6】:

      从 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("~/");
          }
      }
      

      【讨论】:

        【解决方案7】:

        这是一个老问题,但这里是一个现代的 MVC 示例:

        [Authorize]
        public RedirectResult Logout()
        {
            FormsAuthentication.SignOut();
        
            return this.Redirect("/");
        }
        

        您可以通过将Authorize 属性应用于Logout 操作来确保只有登录的人才能调用该操作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-12
          • 2020-01-21
          • 1970-01-01
          • 2011-05-09
          • 1970-01-01
          • 2010-11-11
          • 2011-06-15
          • 2018-08-03
          相关资源
          最近更新 更多