6

我在我的 .NET MVC4 项目中使用 SimpleMembership。在开发过程中,在手动操作/重建数据库时,我遇到了一个在生产中不太可能出现的错误,但我想解决这个问题,但我找不到一种优雅的方式来处理它。

如果在登录应用程序后,您的用户名在数据库中被更改,或者您的用户记录被完全删除,用户将无法再访问应用程序的任何页面......包括允许匿名查看的公共页面,以及登录屏幕。相反,会引发异常 - “未找到名为“用户名”的用户”。

我的应用程序中的所有页面都显示一个部分视图,该视图呈现登录/注销控件。无论数据库中有什么,Request.IsAuthenticated 都会返回 true。应用程序似乎根据 cookie 中的信息认为用户仍在登录,但在数据库中找不到相应的记录。清除 auth cookie 可以解决这个问题,但这不是我想向可能遇到这种情况的用户提供的说明。

我当前的解决方案是在 Global.asax 中捕获该异常,清除 cookie,然后重定向到登录页面。这对我来说似乎完全是hacky。

有没有人对这种情况有更好的解决方案?我从未在使用旧的 .NET Membership 提供程序时遇到过这样的问题……我的期望是,这种情况应该开箱即用,我不应该考虑它……如果记录被更改/deleted 在数据库中,用户应该只是授权失败并自动重定向到登录页面。

4

6 回答 6

2

不确定您首先在哪里拥有身份验证逻辑,但这是我所做的:

在 Global.asax.cs 中:

    protected void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        if (ex.Message.Contains("No user found was found that has the name"))
        {
            FormsAuthentication.SignOut();
            Response.Redirect(Request.RawUrl);
        }
    }

由于抛出的异常只是一个System.InvalidOperationException,因此您无能为力。不是很聪明,但会做需要做的事情。此外,请确保在您重定向到的页面上没有类似的身份验证逻辑IsUserInRole(...),如果是,那么您可能想要将其包装在try{} catch(){}

于 2013-11-04T05:29:17.503 回答
1

您能否在登录后检查数据库缓存或页面某处,用户记录的依赖关系,依赖关系,链删除或可能由于依赖注入而发生。

请检查它或请分享代码..

于 2012-12-13T08:01:10.573 回答
1

我遇到了同样的问题,在我没有登录 MVC 4 站点时IsAuthenticated返回true,导致相同的错误消息。在我们的解决方案中,我有两个带有 SimpleMembership 的 MVC 4 站点,结果我在调试第二个站点时登录了第一个站点。我认为这与设置的 cookie 有关,因为两个站点都在localhosten 上的不同端口下运行,因此两者都将设置相同的身份验证 cookie。我可能需要更改身份验证 cookie 的设置方式。

我认为您可能有不同的问题,但也许我的“解决方案”可以帮助遇到此问题的人。

于 2014-01-13T10:30:11.610 回答
0

覆盖 AuthorizeAttribute:

public sealed class AuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
  protected override bool IsAuthorized(HttpActionContext actionContext)
  {
    try
    {
      return base.IsAuthorized(actionContext);
    }
    catch
    {
      return false; // user name from cookie is no longer in db
    }
  }

  protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
  {
    // handle this exception by global exception filter for redirection to login
    throw new CustomAuthException(); 
  }
}
于 2015-02-12T09:30:25.567 回答
0

我已添加到 Arman Bimatov 响应中,以便在将您重定向到当前页面之前将您注销。通过将您重定向到当前页面,returnURL 将被正确放入查询字符串中。

在 Global.asax.cs 中:

protected void Application_Error(object sender, EventArgs e)
    {
      异常 ex = Server.GetLastError();

      if (ex.Message.Contains("未找到具有该名称的用户"))
      {
        FormsAuthentication.SignOut();
        Response.Redirect(Request.RawUrl);
      }
    }

但是,除非您根据以下问题在 web.config 中有 CustomerErrors 部分,否则这将不起作用: global.asax Application_Error not fire

于 2016-07-25T14:16:38.410 回答
-1

这似乎是从您的开发环境切换到另一台主机时引起的。localhost 正在记住登录 cookie 并尝试将其用于新的简单成员数据库。

正如你所说,它不会发生在生产中。抱歉,我不知道在本地和生产数据库上使用相同登录名的更好方法。

于 2013-02-03T14:17:04.223 回答