.NET MVC4 SimpleMembership错误 - “未找到具有名称xxx的用户”

时间:2012-11-30 23:51:21

标签: asp.net-mvc-4 simplemembership

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

如果在登录应用程序后,您的用户名在数据库中被更改,或者您的用户记录被完全删除,则用户将无法再访问该应用程序的任何页面...包括允许匿名的公共页面视图和登录屏幕。相反,抛出异常 - “未找到具有名称'username'的用户”。

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

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

有没有人有更好的解决方案?我从来没有遇到过使用旧的.NET成员资格提供商这样的问题...我的期望是这种情况应该开箱即用,我不应该考虑到它......如果记录被改变了/在数据库中删除,用户应该只是失败授权并自动重定向到登录页面。

6 个答案:

答案 0 :(得分:1)

您可以在登录后检查数据库缓存或页面的某个位置,用户记录的依赖关系,它所依赖的位置,链删除或由于依赖注入而可能发生的情况。

请检查或请分享代码..

答案 1 :(得分:1)

不确定您的身份验证逻辑首先在哪里,但这就是我的工作:

在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(){}

答案 2 :(得分:1)

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

我认为你可能有不同的问题,但也许我的“解决方案”可以帮助有这个问题的人。

答案 3 :(得分: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(); 
  }
}

答案 4 :(得分:0)

我已添加到Arman Bimatov的回复中,以便在将您重定向到当前页面之前将其记录下来。通过将您重定向到当前页面,returnURL将被正确放入查询字符串中。

在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);
      }
    }

但是,除非您的web.config中有CustomerErrors部分,否则这将无效: global.asax Application_Error not firing

答案 5 :(得分:-1)

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

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