【问题标题】:.NET MVC4 SimpleMembership Error - "No user found was found that has the name xxx".NET MVC4 SimpleMembership 错误 - “找不到名为 xxx 的用户”
【发布时间】:2016-09-02 00:17:14
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: asp.net-mvc-4 simplemembership


    【解决方案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】:

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

      请检查或分享代码..

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 这个解决方案对我有用,我是从另一个站点登录的,当我切换站点时它给了我这个错误。只需清除您的缓存/cookie,它就会正常工作。
        【解决方案4】:

        覆盖 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(); 
          }
        }
        

        【讨论】:

          【解决方案5】:

          我已添加到 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 firing

          【解决方案6】:

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

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

          【讨论】:

          • 好吧,我想它仍然会在生产中发生,我的意思是它可能不会发生,因为在生产情况下我不会手动删除数据库中的记录。这不是切换主机的问题。我没有花太多时间试图弄清楚如何克服这个问题,但它基本上与我的浏览器中的身份验证 cookie 有关,该 cookie 引用了数据库中不再存在的用户......我只是希望能解决这个问题更优雅地开箱即用。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-01
          • 1970-01-01
          • 2018-07-09
          • 2018-06-28
          • 1970-01-01
          • 2015-07-21
          相关资源
          最近更新 更多