Проверка учетных данных пользователей в хранилище авторизованных пользователей (C#)

Скотт Митчелл

Примечание

С момента написания этой статьи поставщики членства ASP.NET были заменены ASP.NET Identity. Мы настоятельно рекомендуем обновить приложения для использования платформы ASP.NET Identity , а не поставщиков членства, которые были представлены на момент написания этой статьи. ASP.NET Identity имеет ряд преимуществ по сравнению с системой членства ASP.NET, в том числе :

  • более высокая производительность;
  • Улучшенная расширяемость и тестируемость
  • Поддержка OAuth, OpenID Connect и двухфакторной проверки подлинности
  • Поддержка удостоверений на основе утверждений
  • Улучшенное взаимодействие с ASP.Net Core

Скачать код или скачать PDF-файл

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

Введение

В предыдущем руководстве мы рассмотрели, как создать новую учетную запись пользователя на платформе членства. Сначала мы рассмотрели создание учетных записей пользователей программным способом с помощью Membership метода класса CreateUser , а затем изучили с помощью веб-элемента управления CreateUserWizard. Однако страница входа в настоящее время проверяет предоставленные учетные данные по жестко закодированному списку пар имени пользователя и пароля. Необходимо обновить логику страницы входа, чтобы она проверяла учетные данные в хранилище пользователей платформы членства.

Как и при создании учетных записей пользователей, учетные данные можно проверять программным или декларативным способом. API членства включает метод программной проверки учетных данных пользователя в хранилище пользователей. Кроме того, ASP.NET поставляется с веб-элементом управления "Вход", который отображает пользовательский интерфейс с текстовыми полями для имени пользователя и пароля и кнопкой для входа.

В этом руководстве мы рассмотрим, как проверить учетные данные пользователя в хранилище пользователей членства с помощью программных средств и элемента управления "Вход". Мы также рассмотрим, как настроить внешний вид и поведение элемента управления для входа. Приступим к работе!

Шаг 1. Проверка учетных данных в хранилище пользователей членства

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

Чтобы проверить пользователя на соответствие платформе членства, используйте Membership метод класса ValidateUser. Метод ValidateUser принимает два входных параметра — username и password — и возвращает логическое значение, указывающее, были ли учетные данные допустимыми. Как и в случае с методом CreateUser , рассмотренным в предыдущем руководстве ValidateUser , метод делегирует фактическую проверку настроенного поставщика членства.

Проверяет SqlMembershipProvider предоставленные учетные данные, получая пароль указанного пользователя с помощью хранимой aspnet_Membership_GetPasswordWithFormat процедуры. Напомним, что пароли пользователей SqlMembershipProvider хранятся в одном из трех форматов: clear, encrypted или hashed. Хранимая aspnet_Membership_GetPasswordWithFormat процедура возвращает пароль в необработанном формате. Для зашифрованных или хэшированных паролей SqlMembershipProvider компонент преобразует password значение, переданное в ValidateUser метод, в эквивалентное зашифрованное или хэш-состояние, а затем сравнивает его с тем, что было возвращено из базы данных. Если пароль, хранящийся в базе данных, совпадает с форматированным паролем, введенным пользователем, учетные данные являются допустимыми.

Давайте обновим страницу входа (~/Login.aspx), чтобы она проверяла предоставленные учетные данные в пользовательском хранилище платформы членства. Мы создали эту страницу входа еще в учебнике Обзор проверки подлинности с помощью форм , создав интерфейс с двумя текстовыми полями для имени пользователя и пароля, флажком "Запомнить меня" и кнопкой "Войти" (см. рис. 1). Код проверяет введенные учетные данные на соответствие жестко закодированному списку пар имени пользователя и пароля (Scott/password, Jisun/password и Sam/password).

Интерфейс страницы входа включает два элемента TextBoxes, CheckBoxList и кнопку

Рис. 1. Интерфейс страницы входа включает в себя два элемента TextBoxes, CheckBoxList и кнопку (нажмите для просмотра полноразмерного изображения)

Пользовательский интерфейс страницы входа может оставаться неизменным, но необходимо заменить обработчик событий кнопки Click Входа кодом, который проверяет пользователя в хранилище пользователей платформы членства. Обновите обработчик событий, чтобы его код отображался следующим образом:

protected void LoginButton_Click(object sender, EventArgs e)
{
    // Validate the user against the Membership framework user store
    if (Membership.ValidateUser(UserName.Text, Password.Text))
    {
        // Log the user into the site
        FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked);
    }
    // If we reach here, the user's credentials were invalid
    InvalidCredentialsMessage.Visible = true;
}

Этот код очень прост. Начнем с вызова Membership.ValidateUser метода , передавая указанные имя пользователя и пароль. Если этот метод возвращает значение true, пользователь войдет на сайт с помощью FormsAuthentication метода RedirectFromLoginPage класса . (Как мы обсуждали в В руководстве FormsAuthentication.RedirectFromLoginPageОбщие сведения о проверке подлинности на основе форм создается запрос проверки подлинности на основе форм, а затем пользователь перенаправляется на соответствующую страницу.) Однако если учетные данные недопустимы, InvalidCredentialsMessage отображается метка, информирующая пользователя о том, что его имя пользователя или пароль неверны.

Вот и все!

Чтобы проверить, работает ли страница входа должным образом, попробуйте войти с помощью одной из учетных записей пользователей, созданных в предыдущем руководстве. Или, если вы еще не создали учетную запись, создайте ее на ~/Membership/CreatingUserAccounts.aspx странице.

Примечание

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

Как платформа членства обрабатывает недопустимые попытки входа

Когда посетитель достигает страницы входа и отправляет свои учетные данные, браузер отправляет HTTP-запрос на страницу входа. Если учетные данные действительны, http-ответ включает запрос проверки подлинности в файл cookie. Таким образом, хакер, пытающийся проникнуть на ваш сайт, может создать программу, которая исчерпывающе отправляет HTTP-запросы на страницу входа с действительным именем пользователя и угадыванием пароля. Если пароль угадывается правильно, страница входа вернет файл cookie запроса проверки подлинности, после чего программа узнает, что она наткнулась на действительную пару имени пользователя и пароля. Благодаря методу подбора такая программа может наткнуться на пароль пользователя, особенно если пароль ненадежный.

Чтобы предотвратить такие атаки методом подбора, платформа членства блокирует пользователя при наличии определенного количества неудачных попыток входа в систему в течение определенного периода времени. Точные параметры можно настроить с помощью следующих двух параметров конфигурации поставщика членства:

  • maxInvalidPasswordAttempts — указывает, сколько недопустимых попыток пароля разрешено пользователю в течение периода времени до блокировки учетной записи. Значение по умолчанию — 5.
  • passwordAttemptWindow — указывает период времени в минутах, в течение которого указанное количество недопустимых попыток входа приведет к блокировке учетной записи. Значение по умолчанию — 10.

Если пользователь заблокирован, он не сможет войти в систему, пока администратор не разблокирует его учетную запись. Если пользователь заблокирован, ValidateUser метод всегда возвращает false, даже если предоставлены допустимые учетные данные. Хотя такое поведение снижает вероятность того, что хакер войдет на ваш сайт с помощью методов подбора, это может в конечном итоге заблокировать действительного пользователя, который просто забыл свой пароль или случайно имеет CAPS LOCK или имеет плохой день ввода.

К сожалению, нет встроенного средства для разблокировки учетной записи пользователя. Чтобы разблокировать учетную запись, можно напрямую изменить базу данных ( изменить IsLockedOut поле в aspnet_Membership таблице для соответствующей учетной записи пользователя) или создать веб-интерфейс, в который перечислены заблокированные учетные записи с параметрами их разблокировки. В будущем мы рассмотрим создание административных интерфейсов для выполнения общих задач, связанных с учетными записями пользователей и ролями.

Примечание

Одним из недостатков ValidateUser метода является то, что если предоставленные учетные данные недопустимы, он не предоставляет никаких объяснений о том, почему. Учетные данные могут быть недопустимыми, так как в хранилище пользователей отсутствует соответствующая пара имени пользователя и пароль, либо пользователь еще не утвержден или пользователь заблокирован. На шаге 4 мы посмотрим, как показать пользователю более подробное сообщение при неудачной попытке входа.

Шаг 2. Сбор учетных данных с помощью веб-элемента управления "Вход"

Веб-элемент управления "Вход" отображает пользовательский интерфейс по умолчанию, очень похожий на интерфейс, созданный в руководстве Обзор проверки подлинности на основе форм. Использование элемента управления "Вход" избавляет нас от необходимости создавать интерфейс для сбора учетных данных посетителя. Кроме того, элемент управления "Вход" автоматически выполняет вход пользователя (при условии, что отправленные учетные данные являются допустимыми), тем самым избавляя нас от необходимости писать какой-либо код.

Давайте обновим Login.aspx, заменив созданный вручную интерфейс и код элементом управления "Вход". Начните с удаления существующей разметки и кода в Login.aspx. Вы можете удалить его прямо или просто закомментировать. Чтобы закомментировать декларативную разметку, заключите ее разделителями <%-- и --%> . Эти разделители можно ввести вручную или, как показано на рисунке 2, можно выделить текст для закомментировать, а затем щелкнуть значок Закомментировать выделенные строки на панели инструментов. Аналогичным образом можно использовать значок Закомментировать выделенные строки, чтобы закомментировать выбранный код в классе кода программной части.

Закомментируйте существующую декларативную разметку и исходный код в Login.aspx

Рис. 2. Закомментируйте существующую декларативную разметку и исходный код в Login.aspx (щелкните для просмотра полноразмерного изображения)

Примечание

Значок Закомментировать выбранные строки недоступен при просмотре декларативной разметки в Visual Studio 2005. Если вы не используете Visual Studio 2008, необходимо вручную добавить <%-- разделители и --%> .

Затем перетащите элемент управления Login из панели элементов на страницу и задайте для его ID свойства значение myLogin. На этом этапе экран должен выглядеть примерно так, как на рис. 3. Обратите внимание, что интерфейс элемента управления "Вход" по умолчанию включает элементы управления TextBox для имени пользователя и пароля, запомнить меня в следующий раз CheckBox и кнопку входа. Существуют также RequiredFieldValidator элементы управления для двух элементов TextBoxes.

Добавление элемента управления

Рис. 3. Добавление элемента управления "Вход" на страницу (щелкните для просмотра полноразмерного изображения)

Теперь все готово. При нажатии кнопки Входа в систему выполняется обратная передача, а элемент управления "Вход" вызовет Membership.ValidateUser метод , передав введенные имя пользователя и пароль. Если учетные данные недопустимы, элемент управления "Вход" отображает сообщение об этом. Однако если учетные данные действительны, элемент управления "Вход" создает запрос проверки подлинности на основе форм и перенаправляет пользователя на соответствующую страницу.

Элемент управления Вход использует четыре фактора, чтобы определить соответствующую страницу, на которой будет перенаправляться пользователь после успешного входа:

  • Указывает, находится ли элемент управления "Вход" на странице входа, как определено параметром в конфигурации проверки подлинности с помощью loginUrl форм; значение по умолчанию для этого параметра — Login.aspx
  • Наличие ReturnUrl параметра querystring
  • Значение свойства элемента управления "Вход"DestinationUrl
  • Значение defaultUrl , указанное в параметрах конфигурации проверки подлинности на основе форм. Значение по умолчанию этого параметра — Default.aspx

На рисунке 4 показано, как элемент управления "Вход" использует эти четыре параметра для принятия соответствующего решения на странице.

Элемент управления Login использует четыре параметра для принятия соответствующего решения на странице.

Рис. 4. Добавление элемента управления входа на страницу (щелкните для просмотра полноразмерного изображения)

Найдите минутку, чтобы протестировать элемент управления "Вход", зайдя на сайт через браузер и выполнив вход в качестве существующего пользователя в платформе членства.

Отрисованный интерфейс элемента управления "Вход" можно настроить с высокой степенью настройки. Существует ряд свойств, влияющих на его внешний вид; Более того, элемент управления Login можно преобразовать в шаблон для точного управления макетом элементов пользовательского интерфейса. В оставшейся части этого шага рассматривается настройка внешнего вида и макета.

Настройка внешнего вида элемента управления входа

Параметры свойств элемента управления "Вход" по умолчанию отображают пользовательский интерфейс с заголовком ("Вход"), элементами управления TextBox и Label для ввода имени пользователя и пароля, флажком "Запомнить меня в следующий раз" и кнопкой "Войти". Внешний вид этих элементов можно настроить с помощью многочисленных свойств элемента управления Login. Кроме того, можно добавить дополнительные элементы пользовательского интерфейса, например ссылку на страницу для создания новой учетной записи пользователя, задав свойство или два.

Давайте потратим несколько минут на то, чтобы пропустить внешний вид нашего элемента управления "Вход". Так как в Login.aspx верхней части страницы уже есть текст с надписью Вход, заголовок элемента управления "Вход" является излишним. Поэтому очистите TitleText значение свойства , чтобы удалить заголовок элемента управления Login.

Поля Имя пользователя и Пароль: Метки слева от двух элементов управления TextBox можно настроить с помощью UserNameLabelText свойств и PasswordLabelTextсоответственно. Давайте изменим имя пользователя: метку на имя пользователя: имя пользователя. Стили Label и TextBox можно настроить с помощью LabelStyle свойств и TextBoxStyleсоответственно.

Свойство Запомнить меня в следующий раз в CheckBox Text можно задать с помощью элемента управления RememberMeText propertyLogin , а его состояние по умолчанию можно настроить с помощью RememberMeSet property (по умолчанию — False). Давайте присвойте свойству RememberMeSet значение True, чтобы по умолчанию флажок CheckBox запомнить меня в следующий раз.

Элемент управления Login предлагает два свойства для настройки макета элементов управления пользовательского интерфейса. Указывает TextLayout property , отображаются ли метки Имя пользователя и Пароль: слева от соответствующих надписей TextBoxes (по умолчанию) или над ними. Указывает Orientation property , расположены ли входные данные имени пользователя и пароля по вертикали (одна над другой) или горизонтально. Я собираюсь оставить для этих двух свойств значения по умолчанию, но я призываю вас попытаться установить для этих двух свойств их значения, отличные от значений по умолчанию, чтобы увидеть полученный эффект.

Примечание

В следующем разделе Настройка макета элемента управления для входа мы рассмотрим использование шаблонов для определения точного макета элементов пользовательского интерфейса элемента управления макетом.

Заключите параметры свойств элемента управления "Вход", задав CreateUserTextдля свойств иCreateUserUrl значение Еще не зарегистрировано? Создайте учетную запись! и ~/Membership/CreatingUserAccounts.aspxсоответственно. При этом в интерфейс элемента управления "Вход" добавляется гиперссылка, указывающая на страницу, созданную в предыдущем руководстве. Свойства и свойства и свойства элементаPasswordRecoveryUrl управления HelpPageText Login работают одинаково, отображая ссылки на страницу справки и страницу восстановления пароля.HelpPageUrlPasswordRecoveryText

После внесения этих изменений в свойства декларативная разметка и внешний вид элемента управления "Вход" должны выглядеть примерно так, как показано на рис. 5.

Значения свойств элемента управления для входа определяют его внешний вид

Рис. 5. Значения свойств элемента управления входа определяют его внешний вид (щелкните, чтобы просмотреть полноразмерное изображение)

Настройка макета элемента управления "Вход"

Пользовательский интерфейс веб-элемента управления Login по умолчанию размещает интерфейс в ФОРМАТЕ HTML <table>. Но что делать, если нам нужен более тонкий контроль над отображаемыми выходными данными? Может быть, мы хотим заменить на <table> ряд тегов <div> . Или что делать, если приложению требуются дополнительные учетные данные для проверки подлинности? Например, многие финансовые веб-сайты требуют, чтобы пользователи предоставляли не только имя пользователя и пароль, но и личный идентификационный номер (ПИН-код) или другую идентификационную информацию. Какими бы ни были причины, можно преобразовать элемент управления Login в шаблон, на основе которого можно явно определить декларативную разметку интерфейса.

Чтобы обновить элемент управления "Вход" для сбора дополнительных учетных данных, необходимо выполнить два действия.

  1. Обновите интерфейс элемента управления Login, чтобы включить веб-элементы управления для сбора дополнительных учетных данных.
  2. Переопределите внутреннюю логику проверки подлинности элемента управления входа, чтобы пользователь прошел проверку подлинности только в том случае, если его имя пользователя и пароль действительны, а также его дополнительные учетные данные.

Для выполнения первой задачи необходимо преобразовать элемент управления Login в шаблон и добавить необходимые веб-элементы управления. Что касается второй задачи, логику проверки подлинности элемента управления "Вход" можно заменять путем создания обработчика событий для события элемента управленияAuthenticate.

Давайте обновим элемент управления Вход, чтобы он запрашивал у пользователей имя пользователя, пароль и адрес электронной почты и проверял подлинность пользователя только в том случае, если указанный адрес электронной почты совпадает с адресом электронной почты в файле. Сначала необходимо преобразовать интерфейс элемента управления "Вход" в шаблон. В смарт-теге элемента управления Login выберите параметр Преобразовать в шаблон.

Преобразование элемента управления

Рис. 6. Преобразование элемента управления входа в шаблон (щелкните для просмотра полноразмерного изображения)

Примечание

Чтобы отменить изменения для элемента управления Вход в его версию предварительного шаблона, щелкните ссылку Сброс в смарт-теге элемента управления.

При преобразовании элемента управления Login в шаблон добавляется LayoutTemplate в декларативную разметку элемента управления с элементами HTML и веб-элементами управления, определяющими пользовательский интерфейс. Как показано на рисунке 7, при преобразовании элемента управления в шаблон из окна Свойства удаляется ряд свойств, таких как , CreateUserUrlи т. д., так как TitleTextэти значения свойств игнорируются при использовании шаблона.

Меньше доступных свойств при преобразовании элемента управления входа в шаблон

Рис. 7. При преобразовании элемента управления входа в шаблон доступно меньше свойств (щелкните для просмотра полноразмерного изображения)

Разметка HTML в может быть изменена LayoutTemplate при необходимости. Аналогичным образом вы можете добавить в шаблон новые веб-элементы управления. Однако важно, чтобы основные веб-элементы управления входа оставались в шаблоне и сохраняли назначенные ID им значения. В частности, не удаляйте и не переименовывайте UserName или Password TextBoxes, RememberMe CheckBox, LoginButton Button, FailureText Label или RequiredFieldValidator элементы управления.

Чтобы получить адрес электронной почты посетителя, необходимо добавить элемент TextBox в шаблон. Добавьте следующую декларативную разметку между строкой Password таблицы (<tr>), содержащей TextBox, и строкой таблицы, содержащей checkBox в следующий раз:

<tr>
 <td align="right">
 <asp:Label ID="EmailLabel" runat="server" AssociatedControlID="Email">Email:</asp:Label>
 </td>
 <td>
 <asp:TextBox ID="Email" runat="server"></asp:TextBox>
 <asp:RequiredFieldValidator ID="EmailRequired" runat="server" 
 ControlToValidate="Email" ErrorMessage="Email is required." 
 ToolTip="Email is required." ValidationGroup="myLogin">*</asp:RequiredFieldValidator>
 </td>
</tr>

После добавления TextBox перейдите Email на страницу через браузер. Как показано на рисунке 8, пользовательский интерфейс элемента управления Login теперь содержит третье текстовое поле.

Элемент управления

Рис. 8. Элемент управления "Вход" теперь содержит текстовое поле для адреса Email пользователя (щелкните для просмотра полноразмерного изображения)

На этом этапе элемент управления "Вход" по-прежнему Membership.ValidateUser использует метод для проверки предоставленных учетных данных. Соответственно, значение, введенное в Email TextBox, не влияет на возможность входа пользователя. На шаге 3 мы рассмотрим, как переопределить логику проверки подлинности элемента управления "Вход", чтобы учетные данные считались действительными только в том случае, если имя пользователя и пароль действительны, а указанный адрес электронной почты совпадает с адресом электронной почты в файле.

Шаг 3. Изменение логики проверки подлинности элемента управления для входа

Когда посетитель предоставляет свои учетные данные и нажимает кнопку Вход, происходит обратная связь и элемент управления "Вход" выполняется через рабочий процесс проверки подлинности. Рабочий процесс начинается с вызова LoggingIn события . Любые обработчики событий, связанные с этим событием, могут отменить операцию входа, задав e.Cancel для свойства значение true.

Если операция входа не отменена, рабочий процесс выполняется путем вызова Authenticate события . Если для события есть обработчик Authenticate событий, он отвечает за определение допустимости предоставленных учетных данных. Если обработчик событий не указан, элемент управления Login использует Membership.ValidateUser метод для определения допустимости учетных данных.

Если предоставленные учетные данные действительны, создается запрос проверки подлинности на основе форм, LoggedIn возникает событие и пользователь перенаправляется на соответствующую страницу. Однако если учетные данные считаются недействительными, возникает LoginError событие и отображается сообщение, информирующее пользователя о том, что его учетные данные были недопустимыми. По умолчанию при сбое элемент управления Login просто задает для свойства FailureText Text элемента управления Label сообщение об ошибке ( Ваша попытка входа не была успешной. Повторите попытку . Однако если свойству элемента управления Login задано FailureAction значение RedirectToLoginPage, элемент управления Login выдает Response.Redirect на страницу входа, добавляя параметр loginfailure=1 querystring (в результате чего элемент управления Login отображает сообщение об ошибке).

На рисунке 9 показана блок-схема рабочего процесса проверки подлинности.

Рабочий процесс проверки подлинности элемента управления для входа

Рис. 9. Рабочий процесс проверки подлинности элемента управления для входа (щелкните для просмотра полноразмерного изображения)

Примечание

Если вам интересно, когда вы будете использовать FailureActionпараметр страницы RedirectToLogin , рассмотрите следующий сценарий. Прямо сейчас на нашей Site.master странице master в левом столбце отображается текст Hello, stranger , если его посетил анонимный пользователь, но предположим, что мы хотим заменить этот текст элементом управления "Вход". Это позволит анонимному пользователю выполнять вход с любой страницы сайта, а не напрямую посещать страницу входа. Однако если пользователю не удалось войти в систему с помощью элемента управления "Вход", отображаемого на странице master, может быть целесообразно перенаправить его на страницу входа (Login.aspx), так как эта страница, скорее всего, содержит дополнительные инструкции, ссылки и другую справку, например ссылки для создания новой учетной записи или получения потерянного пароля, которые не были добавлены на страницу master.

Создание обработчикаAuthenticateсобытий

Чтобы подключить пользовательскую логику проверки подлинности, необходимо создать обработчик событий для события элемента управления "Вход".Authenticate При создании обработчика событий для Authenticate события будет создано следующее определение обработчика событий:

protected void myLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
}

Как видите, обработчику Authenticate событий передается объект типа AuthenticateEventArgs в качестве второго входного параметра. Класс AuthenticateEventArgs содержит логическое свойство с именем Authenticated , которое используется для указания допустимости предоставленных учетных данных. Поэтому наша задача состоит в том, чтобы написать здесь код, который определяет, допустимы ли предоставленные учетные данные, и задать e.Authenticate свойство соответствующим образом.

Определение и проверка предоставленных учетных данных

Используйте свойства и Password свойства элемента управления "Вход"UserName, чтобы определить учетные данные пользователя и пароля, введенные пользователем. Чтобы определить значения, введенные в любые дополнительные веб-элементы управления (напримерEmail, элемент TextBox, добавленный на предыдущем шаге), используйте.FindControlLoginControlID ("controlID"), чтобы получить программную ссылку на веб-элемент управления в шаблоне, свойство которого ID равно controlID. Например, чтобы получить ссылку на Email элемент TextBox, используйте следующий код:

TextBox EmailTextBox = myLogin.FindControl("Email") as TextBox;

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

  1. Убедитесь, что указанные имя пользователя и пароль действительны.
  2. Убедитесь, что введенный адрес электронной почты совпадает с адресом электронной почты в файле для пользователя, пытающегося войти в систему

Для выполнения первого проверка можно просто использовать метод, Membership.ValidateUser как мы видели на шаге 1. Для второго проверка необходимо определить адрес электронной почты пользователя, чтобы сравнить его с адресом электронной почты, введенным в элементе управления TextBox. Чтобы получить сведения о конкретном пользователе, используйте Membership метод класса GetUser.

Метод GetUser имеет ряд перегрузок. Если используется без передачи каких-либо параметров, он возвращает сведения о вошедшего в систему пользователя. Чтобы получить сведения о конкретном пользователе, вызовите GetUser его имя пользователя. В любом случае GetUser возвращает MembershipUser объект , который имеет такие свойства, как UserName, Email, IsApproved, IsOnlineи т. д.

Эти две проверки реализуются в следующем коде. Если оба передаются, то e.Authenticate присваивается значение true, в противном случае назначается false.

protected void myLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
    // Get the email address entered
    TextBox EmailTextBox = myLogin.FindControl("Email") as TextBox;
    string email = EmailTextBox.Text.Trim();

    // Verify that the username/password pair is valid
    if (Membership.ValidateUser(myLogin.UserName, myLogin.Password))
    {
        // Username/password are valid, check email
        MembershipUser usrInfo = Membership.GetUser(myLogin.UserName);
        if (usrInfo != null && string.Compare(usrInfo.Email, email, true) == 0)
        {
            // Email matches, the credentials are valid
            e.Authenticated = true;
        }
        else
        {
            // Email address is invalid...
            e.Authenticated = false;
        }
    }
    else
    {
        // Username/password are not valid...
        e.Authenticated = false;
    }
}

Используя этот код, попытайтесь войти в систему как действительный пользователь, введя правильное имя пользователя, пароль и адрес электронной почты. Повторите попытку, но на этот раз намеренно используйте неправильный адрес электронной почты (см. рис. 10). Наконец, попробуйте в третий раз, используя несуществующее имя пользователя. В первом случае вы должны успешно войти на сайт, но в двух последних случаях вы увидите сообщение о недопустимых учетных данных элемента управления "Вход".

Тито не удается войти в систему при указании неверного адреса Email

Рис. 10. Тито не удается войти в систему при указании неверного Email-адреса (щелкните для просмотра полноразмерного изображения)

Примечание

Как описано в разделе Как платформа членства обрабатывает недопустимые попытки входа на шаге 1, при Membership.ValidateUser вызове метода и передаче недопустимых учетных данных он отслеживает недопустимые попытки входа и блокирует пользователя, если он превышает определенный порог недопустимых попыток в течение указанного периода времени. Так как наша пользовательская логика проверки подлинности вызывает ValidateUser метод , неправильный пароль для допустимого имени пользователя увеличивает недопустимый счетчик попыток входа, но этот счетчик не увеличивается в случае, когда имя пользователя и пароль действительны, но адрес электронной почты неправильный. Скорее всего, такое поведение подходит, так как хакер вряд ли будет знать имя пользователя и пароль, но для определения адреса электронной почты пользователя придется использовать методы подбора.

Шаг 4. Улучшение сообщения о недопустимых учетных данных элемента управления входом

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

Помните, что учетные данные пользователя могут быть недействительными по многим причинам.

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

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

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

Всякий раз, когда пользователь пытается войти с недопустимыми учетными данными, элемент управления Login вызывает свое LoginError событие. Создайте обработчик событий для этого события и добавьте следующий код:

protected void myLogin_LoginError(object sender, EventArgs e)
{
    // Determine why the user could not login...
    myLogin.FailureText = "Your login attempt was not successful. Please try again.";

    // Does there exist a User account for this user?
    MembershipUser usrInfo = Membership.GetUser(myLogin.UserName);
    if (usrInfo != null)
    {
        // Is this user locked out?
        if (usrInfo.IsLockedOut)
        {
            myLogin.FailureText = "Your account has been locked out because of too many invalid login attempts. Please contact the administrator to have your account unlocked.";
        }
        else if (!usrInfo.IsApproved)
        {
            myLogin.FailureText = "Your account has not yet been approved. You cannot login until an administrator has approved your account.";
        }
    }
}

Приведенный выше код начинается с задания свойству элемента управления "Вход" FailureText значения по умолчанию ( Попытка входа не была успешной. Повторите попытку . Затем проверяется, сопоставляется ли предоставленное имя пользователя с существующей учетной записью пользователя. Если это так, он обращается к свойствам и IsApproved результирующего MembershipUser объектаIsLockedOut, чтобы определить, заблокирована ли учетная запись или еще не утверждена. В любом случае FailureText свойство обновляется до соответствующего значения.

Чтобы протестировать этот код, намеренно попытайтесь войти в систему от имени существующего пользователя, но используйте неправильный пароль. Сделайте это пять раз подряд в течение 10 минут, и учетная запись будет заблокирована. Как показано на рисунке 11, последующие попытки входа всегда завершаются сбоем (даже с правильным паролем), но теперь будут отображаться более описательные сведения Ваша учетная запись была заблокирована из-за слишком большого количества недопустимых попыток входа. Обратитесь к администратору, чтобы получить сообщение о разблокировке вашей учетной записи.

Тито выполнил слишком много недопустимых попыток входа и был заблокирован

Рис. 11. Тито выполнил слишком много недопустимых попыток входа и был заблокирован (щелкните для просмотра полноразмерного изображения)

Сводка

До этого руководства страница входа проверяла предоставленные учетные данные на соответствие жестко закодированному списку пар имя пользователя и пароль. В этом руководстве мы обновили страницу, чтобы проверить учетные данные на платформе членства. На шаге 1 мы рассмотрели Membership.ValidateUser использование метода программным способом. На шаге 2 мы заменили созданный вручную пользовательский интерфейс и код элементом управления Вход.

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

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

Счастливого программирования!

Дополнительные материалы

Дополнительные сведения о темах, рассмотренных в этом руководстве, см. в следующих ресурсах:

Об авторе

Скотт Митчелл(Scott Mitchell), автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часах. Скотт может быть доступен в mitchell@4guysfromrolla.com или через его блог по адресу http://ScottOnWriting.NET.

Особая благодарность

Эта серия учебников была рассмотрена многими полезными рецензентами. Ведущими рецензентами этого руководства были Тереса Мерфи и Майкл Оливеро. Хотите просмотреть предстоящие статьи MSDN? Если да, опустите мне строку на mitchell@4GuysFromRolla.com.