5

Я использую инициализатор DropCreateDatabaseAlways, поэтому моя база данных уничтожается каждый раз, когда я запускаю приложение (по крайней мере, я надеюсь, что так). Самое смешное, что я все еще вижу себя вошедшим в систему. Я получаю атрибут Authorize и могу делать опасные вещи. Вероятно, это из-за оставшихся файлов cookie из предыдущего тестирования.ASP.NET MVC аутентифицирует и разрешает несуществующие пользователи

Регистрация/вход в систему моего приложения - это шаблон интернет-приложения MVC 4, не затронутый. Должна ли ASP.NET проверять значения cookie для пользователей, сохраненных в БД? WebSecurity.IsAuthenticated возвращает true и WebSecurity.CurrentUserName возвращает имя. Единственное, что работает как ожидалось, - WebSecurity.CurrentUserId, который возвращает -1. Я новичок, поэтому я могу только догадываться, что это потому, что UserId не хранится в файле cookie и должен быть получен из базы данных.

Я прав? Если да, значит, я должен всегда использовать WebSecurity.CurrentUserId, чтобы определить, вошел ли пользователь в систему? WebSecurity.IsAuthenticated и User.Identity.IsAuthenticated выглядят довольно бесполезными в этом случае. Я могу удалить учетную запись пользователя, и он или она остаются незатронутыми. Что делать по-другому, если я ошибаюсь?

+0

Я должен спросить. Это действительно имеет значение? В производстве, как часто вы будете выбрасывать базу данных? Никогда? Так в чем проблема? Если вы беспокоитесь, не делайте cookie постоянным (удалите любой флажок, который позволяет им войти в систему, и установите значение false для постоянного файла cookie). Да, вы можете удалить их, и если они в настоящее время вошли в систему, они все равно могут получить доступ, но как только они закроют свой браузер, они не смогут снова войти в систему. –

ответ

1

Будет небольшое окно, в котором, если пользователь удален, и они все еще зарегистрированы, что они все равно могут получить доступ к сайту. Поскольку для большинства действий требуется подтверждение идентификатора пользователя, вы можете просто выбросить excpetion и вывести пользователя из системы.

Как правило, база данных не сдувается при каждой сборке, поэтому я предполагаю, что это не вариант использования SimpleMembership. Конечно, вы можете это проверить. Я сделаю еще одно предположение о том, что вы не закрываете свой браузер при восстановлении сайта и развертывании новой базы данных. В сценарии реального мира этих вещей просто не бывает. База данных никогда не сдувается, и идентификатор пользователя никогда не теряется.

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

+0

Мне кажется, что мне недостает безопасности, что (простое) членство не запрашивает базу данных и слепо использует имя пользователя, извлеченное из файла cookie аутентификации. Что хорошего, если пользователь, возможно, уже был удален, и так как мне нужен идентификатор пользователя? –

+1

@MattRicks Предполагается, что после аутентификации учетная запись действительна. Во всех системах, над которыми я работал, я никогда не видел случая, когда пользователь вошел в систему, когда была удалена учетная запись. Не сказать, что этого не может быть, это крайний случай. Почему плохое использование идентификатора пользователя из файла cookie auth? Файл cookie auth зашифрован специально для этой машины. Он доверяет cookie, потому что он устанавливает cookie. –

+2

Ну, я думаю, что метод IsAuthenticated должен работать следующим образом: 1. проверить значения cookie 2. запросить БД для идентификатора пользователя 3. вернуть, имеет ли пользователь файл cookie и существует. Похоже, что у меня только проблема с текущей версией. :) –

0

В нормальном случае добавления Session.Abandon(); к к вашей LogOff действия в AccountController будет выполнять работу клирингового сеанса:

public ActionResult LogOff() 
{ 
    FormsAuthentication.SignOut(); 
    Session.Abandon(); 

    return RedirectToAction("Index", "Home"); 
} 

Так что я думаю, вы можете попробовать добавить Session.Abandon(); в инициализации кода, где вы используете DropCreateDatabaseAlways очистить сессию каждый раз.

1

Если вы хотите по-настоящему проверить, не был ли пользователь удален, вы только имеете, чтобы ознакомиться с базой данных.

Обратите внимание, что пользователи и администраторы работают одновременно. Это означает, что пользователь может быть удален через секунду после его аутентификации. Файл cookie может быть тогда даже одним или двумя секундами (!), И пользователь, возможно, был просто удален.

В самом пессимистичном сценарии пользователь вводит правильное имя пользователя и пароль и успешно входит в систему и получает «извините, ваша учетная запись была удалена» только один запрос позже (поскольку учетная запись действительно была удалена).

0
  • билет Время выдачи обычно шифруются в куки аутентификации, то вы можете использовать его, чтобы потребовать повторной аутентификации для чувствительных зон (Входящие/счетов и т.д.), если с момента входа в систему прошло более X раз.

  • Если вы настаиваете на недействительность всех текущие AUTH билетов на изменения приложений (т.е. базы данных/конфигурацию) вы можете изменить эти настройки в вашем web.config:

    <machineKey validationKey="..." decryptionKey="" /> 
    
1

Пока сеанс аутентификации остается открытым (т. е. браузер теперь закрыт), cookie сеанса остается активным, и MVC предполагает, что пользователь по-прежнему действителен.

Удалить куки с помощью FormsAuthentication.LogOff() если проверка подлинности пользователя (User.Identity.IsAuthenticated == true) и нет действующего пользователя в UserTable (WebSecurity.CurrentUserId == -1).

1

У меня была такая же проблема, но она была решена, указав требуемые роли в атрибуте Authorize. Как только вы это сделаете, он начнет попадать в базу данных и не удастся с ошибкой «пользователь не существует», что вам и нужно.

[Authorize(Roles = "Customer")] 
public class DashboardController : Controller 
Смежные вопросы