Элементы управления PasswordRecovery и ChangePassword
101ASP.NET --- Безопасность в ASP.NET --- Элементы управления PasswordRecovery и ChangePassword
PasswordRecovery
Элемент управления PasswordRecovery полезен в ситуациях, когда пользователь забывает пароль. Он запрашивает имя пользователя, а затем автоматически отображает контрольный вопрос, сохраненный для данного пользователя в хранилище удостоверений. Если пользователь вводит правильный ответ на контрольный вопрос, то его пароль автоматически отправляется по адресу электронной почты данного пользователя. На рисунке ниже показан элемент управления PasswordRecovery в действии:
Этот элемент управления включает в себя три настраиваемых режима представления. В первом пользователь должен ввести свое имя. Когда он щелкает на кнопке отправки, элемент управления через Membership API запрашивает контрольный вопрос пароля из хранилища удостоверений.
Во втором представлении этот вопрос отображается, и пользователю предлагается ввести правильный ответ. Когда правильный ответ введен, автоматически сгенерированный новый пароль либо извлеченный из хранилища старый отправляется пользователю по электронной почте. Адрес электронной почты указывался во время первичной регистрации пользователя (или при его создании в WAT).
Если отправка прошла успешно, элемент управления отображает третье представление - подтверждение. Все настройки, связанные с почтой, устанавливаются через свойства элемента управления. Разумеется, пароль может быть отправлен пользователю, только если он не хеширован. Таким образом, поставщик членства должен быть сконфигурирован так, чтобы пароль сохранялся либо в зашифрованном виде, либо в формате простого текста. Если поставщик членства хранит пароль в хеширований форме, то в этом случае генерируется новый случайный пароль, который и отправляется по электронной почте.
<html>
<head runat="server">
<title>Восстановление пароля</title>
<style>
.TextBox {
padding: 6px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:PasswordRecovery ID="PasswordRecovery1" runat="server"
BackColor="Azure" BorderColor="Black" BorderStyle="Solid">
<MailDefinition From="admin@professorweb.ru" Subject="Восстановления пароля"
Priority="High" />
<TitleTextStyle Font-Bold="true" Font-Italic="true" BorderStyle="Dotted" />
<TextBoxStyle BorderStyle="Double" CssClass="TextBox" />
<FailureTextStyle Font-Bold="true" ForeColor="Red" />
</asp:PasswordRecovery>
</form>
</body>
</html>
Для отправки сообщений по электронной почте этому элементу управления нужен SMTP-сервер. Элемент полагается на класс SmtpClient из пространства имен System.Net.Mail, который можно использовать в приложениях любого типа. Настроить этот класс можно в разделе <system.net> конфигурационного файла приложения. Это значит, что вы должны сконфигурировать почтовый сервер SMTP в файле web.config следующим образом:
<configuration>
<!-- ... -->
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="admin@professorweb.ru">
<network host="localhost" port="25" defaultCredentials="true"/>
</smtp>
</mailSettings>
</system.net>
</configuration>
Подэлемент MailDefinition элемента управления PasswordRecovery позволяет установить основные свойства, как было показано в первом фрагменте кода. К тому же, через свойство BodyFileName подэлемента MailDefinition можно указать имя файла, содержащего текст сообщения электронной почты. Этот файл должен находиться в том же каталоге, что и страница, на которой расположен элемент управления. Если данный элемент управления находится внутри другого пользовательского элемента управления, то файл должен быть в каталоге этого пользовательского элемента.
Элемент управления PasswordRecovery поддерживает различные свойства стилей для задания опций форматирования и компоновки его различных частей (подобно элементу Login). За полным списком поддерживаемых свойств обращайтесь в документацию MSDN; эти свойства подобны тем, что предлагает Login.
Во время процесса восстановления пароля элемент управления PasswordRecovery инициирует несколько различных событий. Их можно обработать для настройки действий, выполняемых данным элементом. В таблице ниже перечислены все эти события:
Событие | Описание |
---|---|
VerifyingUser | Это событие инициируется перед тем, как элемент управления начинает проверку введенного имени пользователя. Проверка имени пользователя означает поиск пользователя в хранилище членства и извлечение информации контрольного вопроса |
UserLookupError | Если введенное в текстовом поле имя пользователя отсутствует в хранилище членства, перед отображением текста о неудаче генерируется это событие |
VerifyingAnswer | Когда пользователь щелкает на кнопке отправки на втором шаге, ответ на вопрос сравнивается с тем, который записан в хранилище членства. Это событие инициируется перед выполнением данного действия |
AnswerLookupError | Это событие инициируется элементом управления, если введенный пользователем ответ не верен |
SendingEmail | Это событие инициируется элементом управления после подтверждения ответа пользователя как корректного и перед тем, как пользователю отправляется сообщение электронной почты |
SendMailError | Это событие инициируется элементом управления, если по какой-то причине сообщение не может быть отправлено (например, почтовый сервер не доступен) |
Эти события можно использовать для подготовки информации перед тем, как она будет обработана элементом управления. Например, если нужно преобразовать все буквы в имени пользователя в нижний регистр перед его сравнением с именами, находящимися в хранилище членства, это можно сделать в событии VerifyingUser. Аналогично VerifyingAnswer можно использовать для обработки информации перед тем, как она будет обработана элементом управления. Оба события получают аргументы типа LoginCancelEventArgs, который имеет свойство Cancel. Установка этого свойства в true позволяет отменить весь шаг обработки.
При перехвате события SendingEmail появляется шанс модифицировать содержимое сообщения электронной почты перед тем, как элемент управления действительно отправит его. Переданный аргумент MailMessageEventArgs содержит свойство Message, представляющее действительное сообщение электронной почты. Модифицируя свойства Message, такие как коллекция Attachments, можно добавлять вложения, настраивать адреса для отправки копии (CC) или делать что-то еще, имеющее отношение к сообщениям электронной почты.
Шаблоны PasswordRecovery
Как и Login, элемент управления PasswordRecovery можно полностью перенастроить, если недостаточно настройки через упомянутые выше свойства и стили. Данный элемент управления поддерживает шаблоны для каждого из своих представлений:
UserNameTemplate содержит все элементы управления, отображаемые на первом шаге процесса восстановления пароля, когда ожидается ввод имени пользователя.
Элементы управления для второго шага, когда выводится контрольный вопрос, помещаются в QuestionTemplate.
И, наконец, элемент поддерживает SuccessTemplate, который состоит из элементов управления, отображаемых после того, как пароль успешно отправлен пользователю по электронной почте.
Каждый шаблон имеет определенные необходимые элементы управления. Например, UserNameTemplate требует текстового поля для ввода имени пользователя. QuestionTemplate - текстового поля для ввода вопроса, a SuccessTemplate - элемента управления Literal для отображения финального подтверждающего сообщения. Шаблон элемента управления PasswordRecovery может выглядеть следующим образом:
<html>
<head runat="server">
<title>Восстановление пароля</title>
<style>
h2 {
background: #00aeee;
color: white;
border-radius: 10px 10px 0 0;
padding:12px;
}
div.container {
background: #969696;
background: linear-gradient(to bottom, #969696 25%,#bababa 100%);
font-family: Courier New;
border-radius: 10px;
margin: 0 auto;
color: white;
}
.button {
padding: 5px;
margin: 10px 30px 0 0;
width: 150px;
}
</style>
</head>
<body>
<form id="form1" runat="server" style="text-align:center">
<asp:PasswordRecovery ID="PasswordRecovery1" runat="server">
<MailDefinition From="admin@professorweb.ru" Subject="Восстановления пароля" Priority="High" />
<UserNameTemplate>
<div class="container">
<h2>Хотите восстановить пароль?</h2>
<asp:Label ID="Label1" runat="server" Text="Введите ваше имя: " ForeColor="white" />
<asp:TextBox ID="UserName" runat="server" />
<br />
<div style="text-align:right">
<asp:Button ID="SubmitButton" CommandName="Submit" runat="server" Text="Далее" CssClass="button" />
</div>
<br />
<span style="color: red">
<asp:Literal ID="FailureText" runat="server" />
</span>
</div>
</UserNameTemplate>
<QuestionTemplate>
<div class="container">
<h2>Хотите восстановить пароль?</h2>
Привет <asp:Literal ID="UserName" runat="server" />! <br />
Пожалуйста ответьте на контрольный вопрос:<br />
<asp:Literal ID="Question" runat="server" /><br />
<asp:TextBox ID="Answer" runat="server" /><br />
<div style="text-align: right">
<asp:Button ID="Button1" CommandName="Submit" runat="Server"
Text="Отправить ответ" CssClass="button" /><br />
</div>
<asp:Literal ID="FailureText" runat="server" /></span>
</div>
</QuestionTemplate>
<SuccessTemplate>
Ваш пароль был успешно выслан на ваш email-адрес:
<asp:Label ID="EmailLabel" runat="server" />!
</SuccessTemplate>
</asp:PasswordRecovery>
</form>
</body>
</html>
И снова если вы используете элементы управления с соответствующими значениями идентификаторов и указываете соответствующие значения CommandName для кнопок, то не должны писать никакого кода, как это и делалось в предыдущих примерах, где шаблоны не применялись. Некоторые из этих элементов управления обязательны для шаблонов, другие - нет. Элементы управления, входящие в шаблоны PasswordRecovery, перечислены в таблице ниже:
Дополнительный шаблон | Идентификатор | Тип элемента | Обязателен? | Комментарии |
---|---|---|---|---|
UserNameTemplate | UserName | System.Web.UI.WebControls | Да | TextBox |
UserNameTemplate | SubmitButton | Все элементы управления, поддерживающие пузырьковое распространение событий | Нет | Name должно быть установлено в Submit |
UserNameTemplate | FailureText | System.Web.UI.WebControls | Нет | Literal |
QuestionTemplate | UserName | System.Web.UI.WebControls | Нет | Literal |
QuestionTemplate | Question | System.Web.UI.WebControls | Нет | Literal |
QuestionTemplate | Answer | System.Web.UI.WebControls | Да | TextBox |
QuestionTemplate | SubmitButton | Все элементы управления, поддерживающие пузырьковое распространение событий | Нет | Name должно быть установлено в Submit |
QuestionTemplate | FailureText | System.Web.UI.WebControls | Нет | Literal |
Кнопкой отправки может служить любой элемент управления, поддерживающий пузырьковое распространение событий и свойство CommandName. Обычно для этой цели можно использовать Button, ImageButton или LinkButton. Свойство CommandName должно быть установлено в Submit, иначе команда не будет распознаваться элементом управления (идентификатор не просматривается и потому может быть установлен в любое значение).
SuccessTemplate не требует никаких элементов со специальными идентификаторами. Таким образом, здесь может быть добавлен любой элемент управления; он нужен только для отображения подтверждений. В предыдущем примере этот шаблон включает элемент Label, который должен отображать адрес электронной почты, куда был отправлен пароль. Установить этот элемент Label можно в процедуре обработки события SendingEmail. Опять-таки, здесь может быть применен метод FindControl для нахождения нужного элемента управления (который на самом деле является дочерним по отношению к шаблонному элементу PasswordRecovery) в соответствующем шаблоне, как показано ниже:
protected void PasswordRecovery1_SendingMail(object sender, MailMessageEventArgs e)
{
Label label =
(Label)PasswordRecovery1.SuccessTemplateContainer.FindControl("EmailLabel");
label.Text = e.Message.To[0].Address;
}
Поскольку элемент управления PasswordRecovery включает более одного шаблона, вызвать метод FindControl непосредственно от имени экземпляра PasswordRecovery не получится. Необходимо выбрать соответствующий шаблонный контейнер (UserNameTemplateContainer, QuestionTemplateContainer или SuccessTemplateContainer). После этого можно работать с полученным элементом управления обычным образом. В предыдущем примере для текста метки устанавливается адрес первого получателя электронной почты. Обычно при восстановлении пароля этот список содержит только одного адресата.
Элемент управления ChangePassword
ChangePassword можно использовать в качестве стандартного элемента управления для предоставления пользователю возможности смены пароля. Этот элемент просто запрашивает имя пользователя и старый пароль. Затем он приглашает пользователя ввести новый пароль и подтвердить его. Элемент ChangePassword можно применять на защищенной странице следующим образом:
<asp:ChangePassword ID="ChangePassword1" runat="server"
BorderStyle="groove" BackColor="aliceblue">
<MailDefinition From="admin@professorweb.ru"
Subject="Изменение пароля"
Priority="high" />
<TitleTextStyle Font-Bold="true" Font-Underline="true"
Font-Names="Verdana" ForeColor="blue" />
</asp:ChangePassword>
И снова этот элемент включает в себя дочерний элемент MailDefinition с теми же настройками, что и PasswordRecovery. Это объясняется тем, что после успешной смены пароля элемент управления может автоматически отправлять электронную почту по адресу пользователя, если для веб-приложения сконфигурирован почтовый сервер. Как и все прочие элементы управления, ChangePassword может настраиваться как через свойства и стили, так и посредством шаблонов. Для настройки элемента управления ChangePassword применяются два шаблона:
ChangePasswordTemplate отображает поля для ввода старого имени пользователя и пароля вместе с новым паролем и полем для его подтверждения.
SuccessTemplate отображает сообщение об успехе, уведомляющее пользователя о том, удалась ли переустановка пароля.
Шаблон ChangePasswordTemplate требует, чтобы были добавлены некоторые специальные элементы управления со специальными идентификаторами и значениями свойств CommandName. Эти значения идентификаторов и CommandName используются в следующем фрагменте кода:
<asp:ChangePassword ID="ChangePassword1" runat="server">
<ChangePasswordTemplate>
Старый пароль:
<asp:TextBox ID="CurrentPassword" runat="server"
TextMode="Password" /><br />
Новый пароль:
<asp:TextBox ID="NewPassword" runat="server"
TextMode="Password" /><br />
Подтвердите новый пароль:
<asp:TextBox ID="ConfirmNewPassword" runat="server"
TextMode="Password" /><br />
<asp:Button ID="ChangePasswordPushButton" CommandName="ChangePassword"
runat="server" Text="Изменить пароль" />
<asp:Button ID="CancelPushButton" CommandName="Cancel"
runat="server" Text="Отмена" /><br />
<asp:Literal ID="FailureText" runat="server"
EnableViewState="False" />
</ChangePasswordTemplate>
<SuccessTemplate>
Ваш пароль был изменен!</td>
<asp:Button ID="ContinuePushButton" runat="server"
CausesValidation="False" CommandName="Continue"
Text="Продолжить" />
</SuccessTemplate>
</asp:ChangePassword>
Элементы управления типа текстовых полей в ChangePasswordTemplate обязательны. Остальные - нет. Если соответствующим образом установить свойства ID и CommandName для кнопок, то никакого дополнительного кода писать не понадобится.