Ошибка .NET MVC4 SimpleMembership — не найден пользователь с именем xxx

Я использую SimpleMembership в своем проекте .NET MVC4. Во время разработки, при ручном манипулировании/восстановлении базы данных, я столкнулся с ошибкой, которая маловероятна в рабочей среде, но я хочу решить эту проблему и не могу найти изящный способ справиться с ней.

Если после входа в приложение ваше имя пользователя будет изменено в базе данных или ваша запись о пользователе будет полностью удалена, пользователь больше не сможет получить доступ ни к одной странице приложения... включая общедоступные страницы, которые разрешают анонимные просмотры, и экран входа в систему. Вместо этого выдается исключение - «Не найден ни один пользователь с именем «имя пользователя»».

Все страницы в моем приложении отображают частичное представление, которое отображает элемент управления входом/выходом из системы. Request.IsAuthenticated возвращает значение true независимо от того, что находится в базе данных. Кажется, приложение считает, что пользователь все еще вошел в систему на основе информации в файле cookie, но в базе данных не может быть найдена соответствующая запись. Очистка файла cookie авторизации решает эту проблему, но это не инструкция, которую я хотел бы предоставить пользователю, который может столкнуться с этим.

Мое текущее решение состоит в том, чтобы поймать это исключение в Global.asax, очистить файлы cookie и перенаправить на страницу входа. Это просто кажется мне совершенно хакерским.

У кого-нибудь есть лучшее решение для этого сценария? Я никогда не сталкивался с подобными проблемами при использовании старого поставщика членства в .NET... я ожидаю, что эта ситуация должна быть рассмотрена прямо из коробки, и мне не нужно отчитываться за это... если запись изменена /deleted в БД, пользователь должен просто не пройти авторизацию и автоматически перенаправиться на страницу входа.


person Gadget27    schedule 30.11.2012    source источник


Ответы (6)


Не уверен, где у вас есть логика аутентификации в первую очередь, но вот что я делаю:

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

person Arman Bimatov    schedule 04.11.2013

Не могли бы вы проверить кеш БД или где-то на странице после входа в систему, зависимость записи пользователя, где она зависит, удаление цепочки или это может происходить из-за инъекции зависимости.

Пожалуйста, проверьте его или поделитесь кодом.

person Karthika Subramanian    schedule 13.12.2012

У меня была такая же проблема: IsAuthenticated возвращал true, когда я не был зарегистрирован на сайте MVC 4, что приводило к тому же сообщению об ошибке. В нашем решении у меня было два сайта MVC 4 с SimpleMembership, и оказалось, что я вошел на первый сайт во время отладки второго сайта. Я думаю, что это будет связано с установленным файлом cookie, поскольку оба сайта работают под другим портом на localhost en, поэтому оба будут устанавливать один и тот же файл cookie аутентификации. Мне, вероятно, потребуется изменить способ установки файла cookie аутентификации.

Я думаю, что у вас может быть другая проблема, но, возможно, мое «решение» может помочь кому-то с этой проблемой.

person Rodi    schedule 13.01.2014
comment
Это решение сработало для меня, я вошел в систему с другого сайта, и когда я переключал сайты, это выдавало мне эту ошибку. Просто очистите кеш/куки, все будет нормально. - person Asad Malik; 15.11.2014

Переопределить 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(); 
  }
}
person blazkovicz    schedule 12.02.2015

Я добавил к ответу Армана Биматова, чтобы он выходил из системы перед перенаправлением на текущую страницу. И перенаправляя вас на текущую страницу, 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);
      }
    }

Однако это не будет работать, если у вас нет раздела CustomerErrors в вашем web.config в соответствии с этим вопросом: global.asax Application_Error не срабатывает

person Daniel - SDS Group    schedule 25.07.2016

Кажется, это вызвано переключением с вашей среды разработки на другой хост. Локальный хост запоминает файл cookie входа и пытается использовать его в новой простой базе данных членства.

Как вы сказали, это не происходит в производстве. Извините, я не знаю лучшего способа, чем использовать один и тот же логин как в локальной, так и в производственной базе данных.

person Pat Tormey    schedule 03.02.2013
comment
Ну, я предполагаю, что это все еще произойдет в производственной среде, все, что я имел в виду, это то, что этого, вероятно, не произойдет, потому что в производственной ситуации я не буду вручную удалять записи в базе данных. Дело не в смене хоста. Я не тратил намного больше времени, пытаясь понять, как это преодолеть, но в основном это связано с файлом cookie аутентификации в моем браузере, который ссылается на пользователя, которого больше нет в базе данных... Я просто хочу, чтобы это было обработано более изящно из коробки. - person Gadget27; 05.02.2013