Файлы к лабораторной работе Вы можете скачать здесь.
Безопасность включает в себя ряд мероприятий, необходимых
для предотвращения несанкционированного доступа к сайту и защиты
информации. Сюда входят аутентификация (распознавание) и
Основные задачи по защите сайта следующие:
Аутентификация нового пользователя начинается с его регистрации.
Пользователю предлагается страница регистрации с текстовыми
полями, через которую у него запрашиваются некоторые идентификационные
данные. По этим данным создается и сохраняется
Теперь при запросе ограниченного ресурса пользователь предъявит свое удостоверение, которое система верифицирует и примет решение: если удостоверение пользователя подтверждается, ему предоставляется доступ к Web-ресурсу, иначе будет предложена регистрация. Процесс аутентификации может выглядеть примерно так

В приложениях ASP.NET аутентификация может быть реализована одним из следующих способов:
System.Web.Security.FormsAuthenticationModuleSystem.Web.Security.WindowsAuthenticationModuleSystem.Web.Security.PassportAuthenticationModuleСистемы коммуникации шифруются с помощью системы
Обычно сервер, которому клиент собирается пересылать важные
данные, маркируется сертификатом. Сертификат - это некоторый
паспорт сервера, подтверждающий тот факт, что ему можно доверять.
Организация, которой принадлежит сервер, приобретает сертификат
у известного
Наиболее популярными центрами
Инсталированный на
Клиент (
Аутентификация (распознавание) на основе форм реализуется
в пространстве имен System.Web.Security классами:
FormsAuthenticationModuleFormsAuthenticationFormsAuthenticationEventArgs FormsAuthenticationTicketFormsIdentityВыбор
этого режима устанавливается только в одном единственном
месте -
<
Аутентификацию форм можно выполнять и с помощью API-интерфейсов Membership и Roles (об этом
позже).
Аутентификация форм основана на удостоверениях (
Для реализации аутентификации форм нужно выполнить следующее:
В файле web.config виртуального корневого каталога сайта необходимо
определить нужные параметры аутентификации, как свойства класса System.Web.Configuration.FormsAuthenticationConfiguration,
из следующего набора:
| Опция | Значение по умолчанию | Описание |
|---|---|---|
Name |
.ASPXAUTH |
Имя |
LoginUrl |
login.aspx |
Определяет страницу регистрации пользователя
при запросе защищенной страницы (login - |
|
30 |
Время жизни |
SlidingExpiration |
false |
Включает режим скользящего устаревания |
Cookieless |
UseDeviceProfile |
Указывает способ пересылки удостоверения пользователя |
Protection |
All |
Задает уровень безопасности None - не
шифровать и не подписывать - только шифровать - только подписыватьAll - шифровать и подписывать |
RequireSSL |
false |
При включении требует передачи через |
EnableCrossAppRedirects |
false |
Разрешает переадресацию между приложениями при использовании аутентификации форм. Оба приложения должны опираться на одно и то же хранилище удостоверений |
DefaultUrl |
default.aspx |
Указывает страницу, на которую направляется пользователь после успешной регистрации, если он напрямую запросил страницу регистрации, указанную в LoginUrl |
Domain |
пусто |
Может указывать |
Path |
/ |
Путь для |
Перечисленные свойства устанавливаются как атрибуты дочернего
дескриптора <forms> секции <.
Вот пример использования полного набора этих атрибутов в файле web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
timeout="20"
slidingExpiration="true"
cookieless="AutoDetect"
protection="All"
requireSSL="false"
enableCrossAppRedirects="false"
defaultUrl="MyDefault.aspx"
domain=""
path="/"
/>
</authentication>
</system.web>
</configuration>
Хоть это и не самый лучший способ хранения удостоверений
пользователей, зато самый простой. Вообще, удостоверения
можно хранить где угодно, только нужно предусмотреть соответствующий
код их сравнения с введенными на странице регистрации данными.
Если удостоверения хранятся в файле web.config,
то их нужно помещать в дочерний для <forms> дескриптор <credentials>.
Вот пример для трех пользователей
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
timeout="20"
slidingExpiration="true"
cookieless="AutoDetect"
protection="All"
requireSSL="false"
enableCrossAppRedirects="false"
defaultUrl="MyDefault.aspx"
domain=""
path="/"
>
<credentials passwordFormat="Clear">
<user name="Admin" password="Root" />
<user name="Petja" password="Xa-xa" />
<user name="Vasja" password="Xo-xo" />
</credentials>
</forms>
</authentication>
</system.web>
</configuration>
Рассмотрим пример <credentials>,
так и программно.
Создайте
пустой проект Web-приложения командой File/New/Web Site с
именем Login
Добавьте
к приложению корневой Website/Add New Item
Заполните
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false">
<credentials passwordFormat="Clear">
<user name="Admin" password="Root" />
<user name="Петя" password="Уфamp;Уф" />
<user name="Вася" password='!$-*?"' />
</credentials>
</forms>
</authentication>
</system.web>
</configuration>
Значение атрибута passwordFormat="Clear" обеспечивает
открытое хранение пользователей в , SHA1 ), использование которых мы рассмотрим чуть позже.
Добавьте
к проекту командой Website/Add New Item страницу без отделенного
кода с именем LoginAddUsers.aspx по
следующему шаблону
Заполните
страницу LoginAddUsers.aspx следующим кодом<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Configuration" %>
<script runat="server">
protected void btnAddUsers_Click(object sender, EventArgs e)
{
// Учетные записи для новых аутентифицированных пользователей
string[,] authUsers = {
{"user1", "password1"},
{"user2", "password2"},
{"user3", "password3"}
};
// Загрузить содержимое корневого Web.config
Configuration myConfig = System.Web.Configuration.
WebConfigurationManager.OpenWebConfiguration("~/");
// Найти содержимое секции system.web
ConfigurationSectionGroup systemWeb = myConfig.SectionGroups["system.web"];
// Найти содержимое секции authentication
System.Web.Configuration.AuthenticationSection authSec =
(System.Web.Configuration.AuthenticationSection)
systemWeb.Sections["authentication"];
// Установить параметр passwordFormat (Clear, MD5, SHA1)
authSec.Forms.Credentials.PasswordFormat = System.Web.Configuration.FormsAuthPasswordFormat.Clear;
// Добавить новых пользователей
for (int i = 0; i < authUsers.Length / 2; i++)
authSec.Forms.Credentials.Users.Add(new System.Web.Configuration.FormsAuthenticationUser(
authUsers[i, 0], authUsers[i, 1]));
// Обновить файл Web.config
myConfig.Save();
// Отсылаем сообщение
lblUsersResult.Text = "Новые пользователи добавлены!!!";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>Административная страница добавления учетных записей в Web.config</h1>
<p>
<asp:Button ID="btnAddUsers" runat="server" Text="Добавить" OnClick="btnAddUsers_Click" /></p>
<p>
<asp:Label ID="lblUsersResult" runat="server"></asp:Label></p>
</div>
</form>
</body>
</html>
Обратите внимание! Чтобы не использовать полные имена классов вместе с их пространствами имен:
В страницах с отделенным кодом используется инструкция using
В страницах с совмещенным кодом используется директива
<%@ Import Namespace="System.Web.Configuration" %>
В режиме
редактирования страницы LoginAddUsers.aspx выполните
команду File/View in Browser
Откройте
файл Web.config и убедитесь, что
страница LoginAddUsers.aspx при выполнении программно
добавила новых пользователей, а также скорректировала
имена старых пользователей путем приведения символов к нижнему
регистру. Но это несущественно, поскольку ASP.NET при
сравнении имен регистр символов не учитывает<credentials passwordFormat="Clear">
<user name="admin" password="Root" />
<user name="петя" password="Уфamp;Уф" />
<user name="вася" password="!$-*?quot;" />
<user name="user1" password="password1" />
<user name="user2" password="password2" />
<user name="user3" password="password3" />
</credentials>
Добавьте
к проекту две страницы без отделенного кода с именами Default.aspx и MyDefault.aspx со
следующим кодом<%@ Page Language="C#" %>
<script runat="server">
protected void SignOutAction_Click(object sender, EventArgs e)
{
// Уничтожить cookie-набор
FormsAuthentication.SignOut();
// Направить на страницу регистрации
//FormsAuthentication.RedirectToLoginPage();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Страница с ограниченным доступом Default.aspx</h1>
<p>
<asp:Button ID="SignOutAction" runat="server"
Text="Отменить регистрацию" OnClick="SignOutAction_Click" />
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/MyDefault.aspx">На страницу MyDefault.aspx...
</asp:HyperLink></p>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<script runat="server">
protected void SignOutAction_Click(object sender, EventArgs e)
{
// Уничтожить cookie-набор
FormsAuthentication.SignOut();
// Направить на страницу регистрации
//FormsAuthentication.RedirectToLoginPage();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Страница с ограниченным доступом MyDefault.aspx</h1>
<p>
<asp:Button ID="SignOutAction" runat="server"
OnClick="SignOutAction_Click" Text="Отменить регистрацию" />
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/Default.aspx">На страницу Default.aspx...
</asp:HyperLink></p>
</div>
</form>
</body>
</html>
В проводнике
решений вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser . Убедитесь,
что пока ASP.NET разрешает пользоваться
этими страницами без регистрации, т.е. любым
Добавьте
в Окончательный
вид файла Web.config должен стать таким
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false">
<credentials passwordFormat="Clear">
<user name="admin" password="Root" />
<user name="петя" password="Уфamp;Уф" />
<user name="вася" password="!$-*?quot;" />
<user name="user1" password="password1" />
<user name="user2" password="password2" />
<user name="user3" password="password3" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
В проводнике
решений вновь вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser . Убедитесь,
что ASP.NET теперь не разрешает пользоваться
этими страницами loginUrl="MyLogin.aspx"Страница регистрации предоставляет пользователю интерфейс
для ввода имени и пароля, принимает их и сравнивает с удостоверениями,
хранящимися на сервере. Если удостоверения хранятся прямо в
Страница регистрации должна включать в себя поля ввода для
получения от пользователя данных удостоверения. Для проверки
достоверности пользовательских данных необходимо использовать
JavaScript -код
на клиенте, а также выполняющие проверку на сервере.
Создайте
заготовку новой страницы с именем MyLogin.aspx без
отделенного кода
Заполните
страницу элементами управления и настройте их
согласно таблице| Элемент | Свойство | Значение | Пояснение |
|---|---|---|---|
Panel |
ID |
MainPanel |
Родительская панель для оформления рамкой |
BorderColor |
Silver |
Цвет рамки | |
|
|
Тип рамки | |
TextBox |
ID |
UsernameText |
Текстовое поле ввода имени пользователя |
RequiredFieldValidator |
ID |
UsernameRequiredValidator |
Проверка достоверности, чтобы привязанное поле не было пустым |
ControlToValidate |
UsernameText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Не заполнено поле " |
Отображать в элементе ValidationSummary при ошибке | |
|
Пустое поле ввода |
||
Text |
* |
Надпись на визуализированном |
|
RegularExpressionValidator |
ID |
UsernameValidator |
|
ControlToValidate |
UsernameText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Неверное |
Отображать в элементе ValidationSummary при ошибке | |
|
Допустимы буквы, цифры, пробелы и подчеркивания |
||
ValidationExpression |
[а-яА-Я\w| ]* |
[] - диапазон пропускаемых символов[]* - символы диапазона могут встречаться в контролируемом
вводе сколько угодно раза-яА-Я - разрешать все буквы русского алфавита\w - разрешать все латинские буквы, цифры и знаки
подчеркивания. Это | - знак ИЛИ, после которого стоит пробел, означает,
что разрешать и пробелыТаким образом: действительными считаются все русские буквы обоих регистров, все латинские буквы обоих регистров, цифры и знаки подчеркивания, а также пробелы. И все это в любом количестве повторений |
|
Text |
* |
Надпись на визуализированном |
|
TextBox |
ID |
PasswordText |
Текстовое поле ввода пароля |
TextMode |
Password |
Ввод отображается звездочками | |
RequiredFieldValidator |
ID |
PwdRequiredValidator |
Проверка достоверности, чтобы привязанное поле не было пустым |
ControlToValidate |
PasswordText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Не заполнено поле "Пароль" |
Отображать в элементе ValidationSummary при ошибке | |
|
Пустое поле ввода |
||
Text |
* |
Надпись на визуализированном |
|
RegularExpressionValidator |
ID |
PwdValidator |
|
ControlToValidate |
PasswordText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Неверный пароль |
Отображать в элементе ValidationSummary при ошибке | |
|
Используются недопустимые символы |
||
ValidationExpression |
[а-яА-Я\w| !"$ |
[] - диапазон пропускаемых символов[]* - символы диапазона могут встречаться в контролируемом
вводе сколько угодно раза-яА-Я - разрешать все буквы русского алфавита\w - разрешать все латинские буквы, цифры и знаки
подчеркивания. Это | - знак ИЛИ, после которого стоит пробел и ряд
других символов, разрешенных для вводаСимволы, которые могут интерпретироваться как служебные,
экранируются обратной косой чертой. Интерпретируемый
HTML-символ амперсанта заменяется неинтерпретируемым
аналогом |
|
Text |
* |
Надпись на визуализированном |
|
Button |
ID |
Button1 |
Кнопка Submit |
Text |
Отправить |
Надпись | |
Label |
ID |
lblResult |
Метка сообщения для заполнения в коде |
ValidationSummary |
ID |
ValidationSummary1 |
Элемент отображения сообщений об ошибках, обнаруженных
|
Интерфейсная часть страницы MyLogin.aspx в режиме проектирования будет такой

Код
страницы MyLogin.aspx будет таким
<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
protected void LoginAction_Click(object sender, EventArgs e)
{
this.Validate();// Исполнить валидаторы на сервере
if (!this.IsValid)// Оценить флаг достоверности
return;// Отправить назад как есть
// Извлечь из web.config и сравнить с введенным
if (FormsAuthentication.Authenticate(UsernameText.Text, PasswordText.Text))
{
// Создать временный cookie-набор (второй параметр false),
// записать в него метку аутентификации и перенаправить
// на исходную запрошенную страницу или MyDefault.aspx
FormsAuthentication.RedirectFromLoginPage(UsernameText.Text, false);
}
else
{
HtmlGenericControl message = new HtmlGenericControl();
message.InnerHtml = "<h2 style='color: Red'>Неверное имя или пароль!</h2>";
form1.Controls.Add(message);
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>Сегодня <% this.Response.Write(DateTime.Now.ToShortDateString()); %> г.</h1>
<h2>
Введите свои имя и пароль</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver"
BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="412px">
<table cellpadding="5" style="width: 100%">
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
Имяnbsp;пользователя:</td>
<td>
nbsp;<asp:TextBox ID="UsernameText" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="UsernameRequiredValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic"
ErrorMessage='Не заполнено поле "Имя пользователя"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="UsernameValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic" ErrorMessage="Неверное имя пользователя"
ToolTip="Допустимы буквы, цифры, пробелы и подчеркивания"
ValidationExpression="[а-яА-Я\w| ]*">*
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
nbsp;Пароль:</td>
<td>
nbsp;<asp:TextBox ID="PasswordText" runat="server"
TextMode="Password" />
</td>
<td>
<asp:RequiredFieldValidator ID="PwdRequiredValidator"
runat="server" ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage='Не заполнено поле "Пароль"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="PwdValidator" runat="server"
ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage="Неверный пароль"
ToolTip="Используются недопустимые символы"
ValidationExpression='[а-яА-Я\w| !"$amp;/()=\-?\*]*'>*
</asp:RegularExpressionValidator>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="Отправить"
OnClick="LoginAction_Click" />
</asp:Panel>
<asp:Label ID="lblResult" runat="server" />
</div>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
</form>
</body>
</html>
В проводнике
решений вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser При такой инфраструктуре аутентификации любой пользователь,
открывший сеанс с приложением, какую бы страницу он не запросил,
будет направляться на страницу регистрации до тех пор, пока
не введет свои данные, хранящиеся в удостоверении конфигурационного
файла. После совпадения удостоверения будет создан -набор
аутентификации со скользящим временем жизни, в котором в зашифрованном
виде будет записан
В нашем файле Web.config до настоящего момента пароли хранились
в виде
В секции <credentials> имеется параметр passwordFormat.
Он предназначен для указания
ASP.NET, в каком формате хранятся значения паролей и какой
алгоритм
Параметр passwordFormat может
принимать одно из трех следующих значений:
Clear - пароль не MD5 - пароль SHA1 - для Для предварительного FormsAuthentication.HashPasswordForStoringInConfigFile().
Добавьте
к проекту страницу HashPasswordPage.aspx с
встроенным скриптом и наполните ее следующим кодом<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Configuration" %>
<script runat="server">
protected void btnHashedPwd_Click(object sender, EventArgs e)
{
// Загрузить содержимое корневого Web.config
Configuration myConfig = System.Web.Configuration.
WebConfigurationManager.OpenWebConfiguration("~/");
// Найти содержимое секции system.web
ConfigurationSectionGroup systemWeb = myConfig.SectionGroups["system.web"];
// Найти содержимое секции authentication
AuthenticationSection authSec =
(AuthenticationSection)
systemWeb.Sections["authentication"];
// Установить параметр passwordFormat, сообщающий, что было хеширование по MD5
authSec.Forms.Credentials.PasswordFormat = FormsAuthPasswordFormat.MD5;
// Извлекаем из коллекции Users старые имена и пароли
int count = authSec.Forms.Credentials.Users.Count;
string[] name = new string[count];
string[] clearTextPwd = new string[count];
int i = 0;
foreach (FormsAuthenticationUser user in authSec.Forms.Credentials.Users)
{
name[i] = user.Name;
clearTextPwd[i] = user.Password;
i++;
}
// Очищаем коллекцию Users
authSec.Forms.Credentials.Users.Clear();
// Добавляем старые имена и новые хешированные пароли
for (i = 0; i < count; i++)
{
// Хешируем исходный пароль
string hashedPwd = FormsAuthentication.
HashPasswordForStoringInConfigFile(clearTextPwd[i], "MD5");
// Добавляем в коллекцию Users
authSec.Forms.Credentials.Users.Add(
new FormsAuthenticationUser(name[i], hashedPwd));
}
// Обновляем файл Web.config
myConfig.Save();
// Отсылаем сообщение
lblHashResult.Text = "Хеширование завершено.<br />"
+ "Повторно не выполнять - будет хеш на хеш!!!";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>
Административная страница хеширования паролей в Web.config</h1>
<p>
<asp:Button ID="btnHashedPwd" runat="server"
OnClick="btnHashedPwd_Click" Text="Хешировать" /></p>
<p>
<asp:Label ID="lblHashResult" runat="server"></asp:Label></p>
</div>
</form>
</body>
</html>
Выполните
страницу HashPasswordPage.aspx,
но только один раз, чтобы повторно не хешировать уже В результате мы получим вариант
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false"
>
<credentials passwordFormat="MD5">
<user name="admin" password="FA03EB688AD8AA1DB593D33DABD89BAD" />
<user name="петя" password="B63974E3EE7B0920FE24DFB8E82FAE81" />
<user name="вася" password="44D4B2D42E830BE0DD43E6830D957C5D" />
<user name="user1" password="7C6A180B36896A0A8C02787EEAFB0E4C" />
<user name="user2" password="6CB75F652A9B52798EB6CF2201057C73" />
<user name="user3" password="819B0643D6B89DC9B579FDFC9094F28E" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
Откройте
в редакторе оболочки страницу Default.aspx
и командой File/View in Browser запустите
ее на выполнениеВначале будет предложена страница регистрации, поскольку конфигурация сайта настроена именно так.
Введите
в странице регистрации MyLogin.aspx user1 и password1Исходные пароли, вводимые пользователями при регистрации,
остались прежними. Но в
Здесь есть одно
Естественно, что подобная страница
До сих пор мы использовали временные
Постоянные
FormsAuthentication.RedirectFromLoginPage( строка_имя ,
true);
FormsAuthentication.SetAuthCookie( строка_имя ,
true);
HttpCookie authCookie = FormsAuthentication.GetAuthCookie( строка_имя ,
true);
this.Response.
Установленный таким способом
FormsAuthentication.SignOut();
Можно также изменить временной статус постоянного
Добавьте
к проекту страницу ModifyPersistentCookieAuth.aspx без файла отделенного
кода и заполните ее так<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
Label message;
protected void Page_Load(object sender, EventArgs e)
{
// Дескриптор центрирования
HtmlGenericControl center = new HtmlGenericControl("center");
form1.Controls.Add(center);
// Текстовая метка с заголовком
Label label = new Label();
center.Controls.Add(label);
label.Text = "<h2>Закрепить аутентификацию за броузером</h2>";
// Кнопки
Button createPersistentCookie = new Button();
center.Controls.Add(createPersistentCookie);
createPersistentCookie.Text = "Создать бессрочный AuthCookie";
createPersistentCookie.Click += new EventHandler(createPersistentCookie_Click);
center.Controls.Add(new HtmlGenericControl("br"));
Button createTemporaryCookie = new Button();
center.Controls.Add(createTemporaryCookie);
createTemporaryCookie.Text = "Создать срочный AuthCookie";
createTemporaryCookie.Click += new EventHandler(createTemporaryCookie_Click);
center.Controls.Add(new HtmlGenericControl("br"));
Button deleteCookie = new Button();
center.Controls.Add(deleteCookie);
deleteCookie.Text = "Удалить AuthCookie";
deleteCookie.Click += new EventHandler(deleteCookie_Click);
center.Controls.Add(new HtmlGenericControl("br"));
// Текстовая метка с сообщением
message = new Label();
center.Controls.Add(message);
message.Text = String.Empty;
}
void createPersistentCookie_Click(object sender, EventArgs e)
{
// Создать бессрочный cookie
HttpCookie authCookie = FormsAuthentication.GetAuthCookie("xx", true);
// Отослать на броузер
this.Response.Cookies.Add(authCookie);
// Сообщить пользователю
message.Text = "Бессрочный AuthCookie создан!";
}
void createTemporaryCookie_Click(object sender, EventArgs e)
{
// Создать вначале бессрочный cookie
HttpCookie authCookie = FormsAuthentication.GetAuthCookie("xx", true);
// Настроить его как временный сроком на 10 дней
authCookie.Expires = DateTime.Now.AddDays(10);
// Отослать на броузер
this.Response.Cookies.Add(authCookie);
// Сообщить пользователю
message.Text = "Срочный AuthCookie создан!";
}
void deleteCookie_Click(object sender, EventArgs e)
{
// Удалить cookie-набор регистрации
FormsAuthentication.SignOut();
// Сообщить пользователю
message.Text = "AuthCookie удален!";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html>
Интерфейс страницы в режиме выполнения будет таким

При закреплении
API Membership является готовым механизмом в ASP.NET,
предназначенным для организации управления аутентификацией
пользователей. Он базируется на аутентификации форм. Единственное отличие,
что хранение пользователей будет осуществляться не в Membership.
Чаще всего к корневому каталогу сайта допускаются все Web.config. Если кто-то запрашивает защищенный ресурс из подкаталога,
система автоматически перенаправляет пользователя на страницу
регистрации.
Для использования API Membership нужно выполнитиь следующие шаги:
SQL Server 2005 создает базу данных и работает
с ней как с отдельным файлом с расширением .mdf.
По умолчанию файлы баз данных размещаются в каталоге
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data
Мы сами можем вручную создать файл базы данных для хранения
удостоверений и добавить в нее таблицы с необходимыми полями.
Но это может несогласоваться с механизмом API Membership,
поскольку он ожидает базу данных определенной структуры. К
тому же нужно будет прописывать в API Membership. Более
простой вариант предусмотрели разработчики Visual Studio
2005, включив поддержку Membership в
утилиту Web Site ( ).
Теперь база данных
нужной структуры для хранения удостоверений будет создана автоматически
при первом запуске
Откройте
файл web.config и удалите из него секцию <credentials> вместе
с внесенными ранее пользователями и временно закомментируйте
секцию 
В результате конфигурационный файл должен стать таким
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false">
</forms>
</authentication>
<!-- Временно закомментировали, чтобы не требовал регистрации
<authorization>
<deny users="?"/>
</authorization>
-->
</system.web>
</configuration>
Запустите
утилиту WAT командой Website/ASP.NET Configuration и
обратите внимание, как долго она запускаетсяЗамечание. Эта утилита может не запускаться, если абсолютный путь к созданному проекту имеет пробелы или кириллицу. В этом случае переместите проект в другое место файловой системы компьютера.
В панели Solution Explorer щелкните на кнопке Refresh Мы видим, что утилита так долго запускалась
потому, что добавила к проекту каталог App_Data (если
до этого его еще не было) и создала в нем базу данных ASPNETDB.MDF,
готовую для хранения удостоверений и согласованную с API
Membership

В панели Solution Explorer двойным щелчком на файле ASPNETDB.MDF откройте
соединение с этой базой данных и ознакомтесь в панели Server
Explorer с ее структурой, типичной для SQL
Server
Такой способ хранения удостоверений пользователей в локальной
базе данных вместе с приложением очень удобен, поскольку позволяет
перемещать сайт в любое место сервера или разворачивать на
любом сервере без дополнительных настроек подключения SQL
Server.
Да и создала
такой, какая нужна системе API Membership.
Это значит, что все классы Membership будут
согласованы с хранилищем удостоверений.
Утилита автоматически создает хранилище
удостоверений только в том случае, если обнаружит в корневом
<
Если на момент запуска утилиты файл конфигурации в корневом
каталоге приложения отсутствует или в нем нет секции аутентификации
на основе форм, то утилита базу данных не создает.
Для того, чтобы проверить работоспособность созданной локальной базы данных, выполните следующее:
Запустите
утилиту WAT командой Website/ASP.NET Configuration
На
вкладке Home щелкните на гиперссылке Provider
Configuration, чтобы перейти на вкладку Provider
На
вкладке Provider щелкните на первой гиперссылке
" Select
a single provider for all site management data "
В отклике,
сгенерированном административной страницей ManageConsolidatedProviders.aspx,
щелкните на гиперссылке Test
В результате страница пришлет ответ, что созданная нами локальная база данных функционирует нормально.
Важно отметить, что хоть утилита автоматически
создала базу данных для поддержки именно Membership.
На данном этапе мы рассмотрим интерактивный способ добавления
пользователей с применением утилиты . В дальнейшем можно
будет создать свои административные страницы для программного
добавления пользователей в это хранилище, используя классы Membership. При этом нужно помнить, что хранилище удостоверений
будет размещаться на удаленном сервере и поддерживать его мы
будем как удаленные пользователи либо через , либо через
собственные административные страницы, также хранящиеся на
сервере.
Для создания новых аутентифицированных пользователей через
утилиту выполните следующее:
В панели Solution Explorer щелкните на пиктограмме ASP.NET
Configuration, чтобы запустить утилиту WAT
Перейдите
на вкладку Security и щелкните на гиперссылке Create
userПоявится следующий отклик утилиты

Сообщение на странице предлагает ввести
В утилите за полем ввода пароля закреплен Membership,
которые, в том числе, будут влиять и на поведение .
Заполните
поля страницы для добавления в хранилище одного пользователя
со следующими характеристикамиUser Name: |
|
Password: |
RootRoot |
: |
RootRoot |
E-mail: |
|
Security : |
У Вас продается славянский шкаф? |
Security : |
Шкаф уже продан, осталась только тумбочка! |
и щелкните на кнопке Create User
После этого действия новый пользователь будет создан в базе данных.
В появившемся
отклике щелкните на кнопке Continue , чтобы
вернутся к интерфейсу добавления следующего пользователя,
либо закройте WAT На данном этапе для проверки аутентификации с использованием API Membership и хранилища БД мы воспользуемся
страницей регистрации MyLogin.aspx.
Ее нужно только немного модифицировать.
Модифицируйте
страницу регистрации MyLogin.aspx,
чтобы код стал таким<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
protected void LoginAction_Click(object sender, EventArgs e)
{
this.Validate();// Исполнить валидаторы на сервере
if (!this.IsValid)// Оценить флаг достоверности
return;// Отправить назад как есть
// Извлечь из базы данных и сравнить с введенным
if (Membership.ValidateUser(UsernameText.Text, PasswordText.Text))
{
// Создать временный cookie-набор (второй параметр false),
// записать в него метку аутентификации и перенаправить
// на исходную запрошенную страницу или defaultUrl="MyDefault.aspx"
// с созданием coockie-набора только на период сеанса
FormsAuthentication.RedirectFromLoginPage(UsernameText.Text, false);
}
else
{
HtmlGenericControl message = new HtmlGenericControl();
message.InnerHtml = "<h2 style='color: Red'>Неверное имя или пароль!</h2>";
form1.Controls.Add(message);
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>Сегодня <% this.Response.Write(DateTime.Now.ToShortDateString()); %> г.</h1>
<h2>
Введите свои имя и пароль</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver"
BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="412px">
<table cellpadding="5" style="width: 100%">
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
Имяnbsp;пользователя:</td>
<td>
nbsp;<asp:TextBox ID="UsernameText" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="UsernameRequiredValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic"
ErrorMessage='Не заполнено поле "Имя пользователя"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="UsernameValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic" ErrorMessage="Неверное имя пользователя"
ToolTip="Допустимы буквы, цифры, пробелы и подчеркивания"
ValidationExpression="[а-яА-Я\w| ]*">*
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
nbsp;Пароль:</td>
<td>
nbsp;<asp:TextBox ID="PasswordText" runat="server"
TextMode="Password" />
</td>
<td>
<asp:RequiredFieldValidator ID="PwdRequiredValidator"
runat="server" ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage='Не заполнено поле "Пароль"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="PwdValidator" runat="server"
ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage="Неверный пароль"
ToolTip="Используются недопустимые символы"
ValidationExpression='[а-яА-Я\w| !"$amp;/()=\-?\*]*'>*
</asp:RegularExpressionValidator>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="Отправить"
OnClick="LoginAction_Click" />
</asp:Panel>
<asp:Label ID="lblResult" runat="server" />
</div>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
</form>
</body>
</html>
Запустите
приложение с любой страницы и введите User
Name: |
|
Password: |
RootRoot |
С помощью
утилиты WAT добавьте в хранилище еще несколько пользователей
и убедитесь, что аутентификация на основе Membership и хранилища
удостоверений в БД работаетПри добавлении новых пользователей следует иметь ввиду, что
реляционной
таблицы aspnet_Users и
является основой для формирования поля как
В панели Server Explorer установите соединение с
базой данных ASPNETDB двойным щелчком указателя
мыши на пиктограмме базы
Для
таблиц aspnet_Users и aspnet_Membership выполните
команду Show Table Data контекстного меню
После таких действий откроются таблицы aspnet_Users и aspnet_Membership,
в которых можно найти информацию о созданных пользователях.
Для того, чтобы увидеть структуру таблиц, следует выполнить
для них команду Open Table контекстного меню.
Интерфейс API Membership включает в себя
следующие классы пространства имен System.Web.Security:
Membership - статический класс, имеющий ряд полезных методов
MembershipCreateUserException - исключение,
генерируемое ошибкой MembershipPasswordException - исключение при невозможности
извлечения пароляMembershipUser - объект этого класса содержит всю информацию
о пользователе и возвращается методом Membership.GetUser()MembershipUserCollection - коллекция пользователей,
извлекаемая методом Membership.GetAllUsers()MembershipProvider - базовый класс для MembershipProviderCollection - коллекция доступных для
приложения поставщиков на данной машинеSqlMembershipProvider - поставщик для работы с базами данных
SQL ServerActiveDirectoryMembershipProvider - поставщик для работы
со службой ActiveDirectoryMembershipUser - класс поддержки пользователя,
расширенный для работы со службой Используя API Membership, можно программно решать, например,
следующие задачи:
Для создания и удаления пользователей следует применить перегруженные
статические методы CreateUser() и класса Membership.
Нужно создать административные страницы, содержащие требуемые
поля для ввода информации. Поля можно контролировать
Метод CreateUser() имеет несколько перегрузок,
из которых простейшая принимает только имя и пароль. В то же
время более полные CreateUser() содержит экземпляр
перечисления MembershipCreateStatus в качестве
CreateUser(), включающую контрольный
вопрос и ответ, чтобы избежать выброса исключения MembershipCreateUserException.
Удаление пользователя выполняется методом Membership.,
которому передается в качестве параметра уникальное
В качестве примера создадим собственную страницу добавления,
имеющую аналогичную функциональность с , и
отдельно страницу удаления пользователя в БД. Для простоты
эти страницы мы переделаем из страницы регистрации MyLogin.aspx.
Скопируйте
страницу MyLogin.aspx и присвойте копии
имя AddUserMembership.aspxCustomValidator.
С помощью этого элемента реализуем проверку достоверности на
клиенте и на сервере.
Неалфавитно-цифровые символы представим
в виде -кодов согласно следующей таблице
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ||||||||||
| 1 | ||||||||||
| 2 | ||||||||||
| 3 | ! | " | # | $ | % | ' | ||||
| 4 | ( | ) | * | + | , | . | / | |||
| 5 | : | ; | ||||||||
| 6 | < | = | > | ? | @ | |||||
| 7 | ||||||||||
| 8 | ||||||||||
| 9 | [ | \ | ] | ^ | _ | |||||
| 10 | ||||||||||
| 11 | ||||||||||
| 12 | { | | | } | ~ |
Строка -кодов неалфавитно-цифровых символов на JavaScript будет такой:
var nonAlphanumericCharactersString = String.fromCharCode(33,34,35,36,37,38,39,40,41,42,43,44,45,46,
58,59,60,61,62,63,64,91,92,93,94,95,123,124,125,126);
Переделайте
интерфейсную и скриптовую части страницы, чтобы она стала
такой<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
// Блок на C# по умолчанию
protected void Page_Load(object sender, EventArgs e)
{
// Вынесли из интерфейсной части из-за большой ширины листинга
passwordValidator.ErrorMessage =
"Пароль должен иметь длину не менее 7 символов"
+ " и содержать хотя бы один неалфавитно-цифровой символ";
}
protected void AddUserMembership_Click(object sender, EventArgs e)
{
this.Validate();// Исполнить валидаторы на сервере
if (!this.IsValid)// Оценить флаг достоверности
return;// Отправить назад как есть
// Создаем экземпляр перечисления
MembershipCreateStatus status;
// Попытка добавить
try
{
Membership.CreateUser(
username.Text,
password.Text,
email.Text,
question.Text,
answer.Text,
true,
out status
);
lblResult.Text = String.Empty;
switch (status)
{
case MembershipCreateStatus.DuplicateUserName:
lblResult.Text = "Дублированное имя пользователя<br/>";
goto default;
case MembershipCreateStatus.ProviderError:
lblResult.Text = "Ошибка Поставщика<br/>";
goto default;
default: // Дальше лень анализировать
lblResult.Text += "Пользователь не создан";
lblResult.ForeColor = System.Drawing.Color.Red;
break;
case MembershipCreateStatus.Success:
// Выдаем успешную информацию
lblResult.Text = "Пользователь " + username.Text
+ " создан успешно!";
// Рекурсивно очищаем все текстовые поля ввода
EmptyTextBox(form1.Controls);
lblResult.Text += "<br/>Поля ввода очищены";
break;
}
}
// Откат
catch (MembershipCreateUserException ex)
{
lblResult.Text = "<h2 style='color: Red'>Ошибка создания пользователя</h2>";
System.Diagnostics.Debug.WriteLine("Exception: "
+ ex.Message);
}
}
private void EmptyTextBox(ControlCollection controls)
{
foreach (Control ctrl in controls)
{
if (ctrl is TextBox)
((TextBox)ctrl).Text = String.Empty;
// Идем в глубину иерархической цепочки и ищем дочерние элементы
if (ctrl.Controls != null)
EmptyTextBox(ctrl.Controls);
}
}
</script>
<script language="C#" runat="server">
// Еще один блок с явным указанием C#, хотя можно атрибут языка и не указывать
// Проверка допустимости пароля на сервере
// Обработчик события ServerValidate элемента CustomValidator
protected void passwordValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
string data = args.Value;
// Установить начальное значение флага достоверности
args.IsValid = false;
// Проверить длину пароля
if (data.Length < 7)
return;
// Проверить наличие неалфавитноцифрового символа
// Формируем массив неалфавитноцифровых символов по их кодам,
// чтобы не связываться с интерпретируемыми символами
int[] nonAlphanumericCharactersCode =
{33,34,35,36,37,38,39,40,41,42,43,44,45,46,
58,59,60,61,62,63,64,91,92,93,94,95,123,124,125,126};
// Перебираем символы пользовательского ввода
foreach (char ch in data)
{
for (int i = 0; i < nonAlphanumericCharactersCode.Length; i++)
if (ch == Convert.ToChar(nonAlphanumericCharactersCode[i]))
{
// Пароль допустим
args.IsValid = true;
return;
}
}
}
</script>
<script language="javascript" type="text/javascript">
// Проверка допустимости пароля на клиенте. Работает при включенном
// по умолчанию свойстве EnableClientScript элемента CustomValidator
function ValidatePassword(source, args)
{
// Расщепить строку на массив символов с пустым разделителем
var data = args.Value.split("");
// Установить начальное значение флага достоверности
args.IsValid = false;
// Проверить длину пароля
if(data.length < 7)
return;
// Проверить наличие неалфавитноцифрового символа
// Формируем строку неалфавитноцифровых символов по их кодам,
// чтобы не связываться с интерпретируемыми символами
var nonAlphanumericCharactersString =
String.fromCharCode(33,34,35,36,37,38,39,40,41,42,43,44,45,46,
58,59,60,61,62,63,64,91,92,93,94,95,123,124,125,126);
for(var ch in data)
{
if(nonAlphanumericCharactersString.indexOf(data[ch]) != -1)
{
// Пароль допустим
args.IsValid = true;
return;
}
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Добавление пользователей в БД</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h2 id="H2_1" runat="server">
Введите учетную запись для добавления пользователя</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver" BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="364px">
<table cellpadding="5" style="width: 137%">
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
Имяnbsp;пользователя:
</td>
<td>
nbsp;<asp:TextBox ID="username" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="usernameRequiredValidator"
runat="server" ControlToValidate="username"
ErrorMessage='Не заполнено поле "Имя пользователя"'
Display="Dynamic">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
nbsp;Пароль:
</td>
<td>
nbsp;<asp:TextBox ID="password" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="passwordRequiredValidator"
runat="server" ControlToValidate="password"
ErrorMessage='Не заполнено поле "Пароль"'
Display="Dynamic">*</asp:RequiredFieldValidator>
<asp:CustomValidator ID="passwordValidator" runat="server"
ControlToValidate="password"
Display="Dynamic"
ClientValidationFunction="ValidatePassword"
OnServerValidate="passwordValidator_ServerValidate">*</asp:CustomValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
E-mail:</td>
<td>
nbsp;<asp:TextBox ID="email" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="emailRequiredValidator"
runat="server" ControlToValidate="email"
ErrorMessage='Не заполнено поле "E-mail"'
Display="Dynamic">*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="emailValidator" runat="server"
ControlToValidate="email" ErrorMessage="Неверный E-mail"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
Display="Dynamic">*</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
Контрольный вопрос:</td>
<td>
nbsp;<asp:TextBox ID="question" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="questionRequiredValidator"
runat="server" ControlToValidate="question"
ErrorMessage='Не заполнено поле "Контрольный вопрос"'
Display="Dynamic">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
Контрольный ответ:</td>
<td>
nbsp;<asp:TextBox ID="answer" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="answerRequiredValidator"
runat="server" ControlToValidate="answer"
ErrorMessage='Не заполнено поле "Контрольный ответ"'
Display="Dynamic">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td colspan="4" align="center">
<asp:Button ID="btnAddUser" runat="server"
Text="Добавить" OnClick="AddUserMembership_Click" />
</td>
</tr>
</table>
</asp:Panel>
<asp:Label ID="lblResult" runat="server" Font-Bold="True"
Font-Size="Large" ForeColor="Blue" />
</div>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
</form>
</body>
</html>
Выполните
страницу AddUserMembership.aspx и убедитесь
в работоспособности рассматриваемого механизма добавления
пользователей в БД SQL ServerТеперь рассмотрим вопрос удаления пользователей. Он намного
проще, чем создание. Нужно только применить метод System.Web.Security.Membership.,
который имеет две
public static bool DeleteUser ( string
username ) - удаляет
по имени пользователя все связанные с ним данные из
всех таблиц БДpublic static bool DeleteUser ( string
username , bool deleteAllRelatedData ) - удаляет пользователя
только из таблицы aspnet_Users,
если флаг равен false. Иначе удаляет все
связанные с пользователем данные при флаге равном trueОбе true, если пользователь успешно
удален, иначе false.
Разработайте
из копии страницы MyLogin.aspx административную
страницу удаления пользователей DeleteUserMembership.aspx, которая будет примерно
такой<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
protected void DeleteUser_Click(object sender, EventArgs e)
{
if (Membership.DeleteUser(username.Text))
{
lblResult.Text="Пользователь " + username.Text
+ " успешно удален";
username.Text = "";
}
else
{
lblResult.Text = "Пользователь не удален";
lblResult.ForeColor = System.Drawing.Color.Red;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Удаление пользователей из БД</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h2>
Введите имя удаляемого пользователя</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver"
BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="412px">
<table cellpadding="5" style="width: 100%">
<tr>
<td align="right" height="43" style="width: 167px">
Имяnbsp;пользователя:</td>
<td>
nbsp;<asp:TextBox ID="username" runat="server" />
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="Удалить"
OnClick="DeleteUser_Click" /></asp:Panel>
<asp:Label ID="lblResult" runat="server" Font-Bold="True"
Font-Size="Large" ForeColor="Blue">
</asp:Label>
</div>
</form>
</body>
</html>
Испытайте
страницу удаления пользователейДля получения списка пользователей применяют метод Membership.GetAllUsers(),
а для извлечения конкретного пользователя - метод Membership.GetUser().
Рассмотрим пример, в котором будем использовать элемент для представления пользователей в виде таблицы.
Добавьте
к проекту страницу GetUsersMembership.aspx без
файла отделенного кода и назначьте ее стартовой
Заполните
страницу следующим кодом<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
// Вынесли поле класса для видимости в обработчиках
MembershipUserCollection myUsers = new MembershipUserCollection();
protected void Page_Load(object sender, EventArgs e)
{
// Скрываем таблицу деталей
tableDetails.Visible = false;
lblUser.Visible = false;
if (checkUser.Checked)
{
// Извлекаем одного пользователя
if (txtUser.Text.Length == 0)
{
lblUsersList.Text = "Введите имя пользователя";
return;
}
try // Попытка
{
string user = Server.HtmlEncode(txtUser.Text);
myUsers = new MembershipUserCollection();
myUsers.Add(Membership.GetUser(user));
}
catch // Откат
{
lblUsersList.Text = "Пользователь не найден";
return;
}
}
else
{
// Извлекаем всех пользователей
myUsers = Membership.GetAllUsers();
}
// Подключаем к сетке извлеченную информации и наполняем элемент
UsersGridView.DataSource = myUsers;
UsersGridView.DataBind();
}
// Обработчик щелчков на ссылки столбца отображения деталей
protected void UsersGridView_SelectedIndexChanged(object sender, EventArgs e)
{
if (UsersGridView.SelectedIndex >= 0)
{
// Заполняем интерфейсные элементы отображаемой информацией,
// адресуясь к конкретному пользователю по ключевому имени,
// заданному параметром DataKeyNames="UserName" элемента GridView
MembershipUser currentUser =
myUsers[(string)UsersGridView.SelectedValue];
lblUserName.Text = currentUser.UserName;
lblEmail.Text = currentUser.Email;
lblPasswordQuestion.Text = currentUser.PasswordQuestion;
lblLastLoginDate.Text = currentUser.LastLoginDate.ToLongDateString();
txtComment.Text = currentUser.Comment;
checkIsApproved.Checked = currentUser.IsApproved;
checkIsLockedOut.Checked = currentUser.IsLockedOut;
// Включаем видимость таблицы деталей
tableDetails.Visible = true;
lblUser.Visible = true;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>
<asp:Label ID="lblUsersList" runat="server" Font-Bold="true"
Text="Список зарегистрированных пользователей"></asp:Label>
</h2>
<p>Конкретный пользователь:
<asp:CheckBox ID="checkUser" runat="server" />
<asp:TextBox ID="txtUser" runat="server"></asp:TextBox>
<asp:Button ID="btnUser" runat="server" Text="Получить" /></p>
<asp:GridView ID="UsersGridView" runat="server"
DataKeyNames="UserName"
AutoGenerateColumns="False"
OnSelectedIndexChanged="UsersGridView_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="UserName" HeaderText="Имя" />
<asp:BoundField DataField="Email" HeaderText="email" />
<asp:BoundField DataField="CreationDate" HeaderText="Создан" />
<asp:CommandField ShowSelectButton="True" HeaderText="Детали"
SelectText="Показать" />
</Columns>
</asp:GridView>
<h2>
<asp:Label ID="lblUser" runat="server"
Text="Подробности для выделенного пользователя"
Visible="False" Font-Bold="true"></asp:Label>
</h2>
<table id="tableDetails" bordercolor="#0000FF"
runat="server">
<tr>
<td width="50%">
Пользователь:</td>
<td>
<asp:Label ID="lblUserName" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
email:</td>
<td>
<asp:Label ID="lblEmail" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Контрольный вопрос:</td>
<td>
<asp:Label ID="lblPasswordQuestion" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Дата последней регистрации:</td>
<td>
<asp:Label ID="lblLastLoginDate" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Комментарии:</td>
<td>
<asp:TextBox ID="txtComment" runat="server" TextMode="MultiLine"
></asp:TextBox></td>
</tr>
<tr>
<td width="50%">
Проверенный:</td>
<td>
<asp:CheckBox ID="checkIsApproved" runat="server" /></td>
</tr>
<tr>
<td width="50%">
Заблокирован:</td>
<td>
<asp:CheckBox ID="checkIsLockedOut" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Интерфейсная часть страницы представлена элементом и
текстовыми метками, спозиционированными в серверной таблице.
Значения параметров элемента представляют
собой имена полей таблиц aspnet_Users и aspnet_Membership базы
данных

Установка в элементе управления свойства DataKeyNames=" позволяет
извлекать значения поля через ,
что очень удобно при получении подробностей о конкретном пользователе
из коллекции пользователей.
Метод Membership. GetUser() возвращает
объект запрошенного пользователя, свойства которого мы отображаем
в текстовых элементах, скомпонованных в таблице. Привязка
к свойствам объекта пользователя выполняется в обработчике
события SelectedIndexChanged элемента управления .
Результат работы страницы GetUsersMembership.aspx будет
примерно таким

Если у нас есть экземпляр класса MembershipUser, то мы можем обновить его свойства, имеющие аксессор set, а именно:
Comment Email IsApproved LastActivityDate LastLoginDate Для этого используется статический метод Membership. UpdateUser().
Получите из страницы GetUsersMembership.aspx копию с именем UpdateUserMembership.aspx
Скорректируйте страницу UpdateUserMembership.aspx, чтобы обновляемые параметры таблицы деталей размещались в текстовых полях
Закрепите за полем txtEmail элементы проверки достоверности RequiredFieldValidator и RegularExpressionValidatorОкончательный код страницы UpdateUserMembership.aspx будет таким
<%@ Page Language="C#" EnableViewState="false" %>
<%@ Import Namespace="System.Web.Security" %>
<script runat="server">
// Вынесли поле для видимости в обработчиках
MembershipUserCollection myUsers = new MembershipUserCollection();
protected void Page_Load(object sender, EventArgs e)
{
// Скрываем таблицу деталей
tableDetails.Visible = false;
lblUser.Visible = false;
// Извлекаем всех пользователей
myUsers = Membership.GetAllUsers();
// Подключаем к сетке извлеченную информации и наполняем элемент
UsersGridView.DataSource = myUsers;
UsersGridView.DataBind();
}
// Обработчик щелчков на ссылки столбца отображения деталей
protected void UsersGridView_SelectedIndexChanged(object sender, EventArgs e)
{
if (UsersGridView.SelectedIndex >= 0)
{
// Заполняем интерфейсные элементы отображаемой информацией,
// адресуясь к конкретному пользователю по ключевому имени,
// заданному параметром DataKeyNames="UserName" элемента GridView
MembershipUser currentUser =
myUsers[(string)UsersGridView.SelectedValue];
lblUserName.Text = currentUser.UserName;
txtEmail.Text = currentUser.Email;
lblPasswordQuestion.Text = currentUser.PasswordQuestion;
lblLastLoginDate.Text = currentUser.LastLoginDate.ToLongDateString();
txtComment.Text = currentUser.Comment;
checkIsApproved.Checked = currentUser.IsApproved;
checkIsLockedOut.Checked = currentUser.IsLockedOut;
// Включаем видимость таблицы деталей
tableDetails.Visible = true;
lblUser.Visible = true;
}
}
protected void btnUpdate_Click(object sender, EventArgs e)
{
if (UsersGridView.SelectedIndex >= 0)
{
// Адресуемся к выделенному пользователю
MembershipUser currentUser =
myUsers[(string)UsersGridView.SelectedValue];
// Избавляемся от возможных управляющих символов
// в пользовательском вводе
currentUser.Email = Server.HtmlEncode(txtEmail.Text);
currentUser.Comment = Server.HtmlEncode(txtComment.Text);
currentUser.IsApproved = checkIsApproved.Checked;
// Сбрасываем в базу данных
Membership.UpdateUser(currentUser);
// Обновить содержимое GridView из БД, поскольку
// этот обработчик выполнится после Page_Load
myUsers = Membership.GetAllUsers();// Извлекаем пользователей
UsersGridView.DataBind();
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>
<asp:Label ID="lblUsersList" runat="server" Font-Bold="true"
Text="Список зарегистрированных пользователей"></asp:Label>
</h2>
<asp:GridView ID="UsersGridView" runat="server"
DataKeyNames="UserName"
AutoGenerateColumns="False"
OnSelectedIndexChanged="UsersGridView_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="UserName" HeaderText="Имя" />
<asp:BoundField DataField="Email" HeaderText="email" />
<asp:BoundField DataField="CreationDate" HeaderText="Создан" />
<asp:CommandField ShowSelectButton="True" HeaderText="Детали"
SelectText="Показать" />
</Columns>
</asp:GridView>
<h2>
<asp:Label ID="lblUser" runat="server"
Text="Подробности для выделенного пользователя"
Visible="False" Font-Bold="true"></asp:Label>
</h2>
<table id="tableDetails" bordercolor="#0000FF"
runat="server">
<tr>
<td width="50%">
Пользователь:</td>
<td>
<asp:Label ID="lblUserName" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
<font>email:</font></td>
<td>
<asp:TextBox ID="txtEmail" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator
ID="RequiredFieldValidator1" runat="server"
ControlToValidate="txtEmail" Display="Dynamic">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1"
runat="server" ControlToValidate="txtEmail"
Display="Dynamic"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
</asp:RegularExpressionValidator></td>
</tr>
<tr>
<td width="50%">
Контрольный вопрос:</td>
<td>
<asp:Label ID="lblPasswordQuestion" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Дата последней регистрации:</td>
<td>
<asp:Label ID="lblLastLoginDate" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
<font>Комментарии:</font></td>
<td>
<asp:TextBox ID="txtComment" runat="server" TextMode="MultiLine"
></asp:TextBox></td>
</tr>
<tr>
<td width="50%">
<font>Проверенный:</font></td>
<td>
<asp:CheckBox ID="checkIsApproved" runat="server" /></td>
</tr>
<tr>
<td width="50%">
Заблокирован:</td>
<td>
<asp:CheckBox ID="checkIsLockedOut" runat="server" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<asp:Button ID="btnUpdate" runat="server" Text="Обновить"
OnClick="btnUpdate_Click" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Вкладка Login панели Toolbox содержит
компоненты, которые обеспечивают пользовательский интерфейс
и функциональность для выполнения большинства типовых операций
членства и безопасности.

Это следующие компоненты:
Login - предоставляет два поля для ввода
имени пользователя и пароля, а также кнопку для отправки
на проверку удостоверения пользователя. По умолчанию проверка
выполняется через API MembershipLoginView - позволяет отображать разные
наборы элементов управления для разных категорий пользователейPasswordRecovery - предоставляет необходимый
интерфейс для запроса контрольного ответа и обеспечивает
повторную отправку пользователю утраченного пароля через
электронную почтуLoginStatus - проверяет состояние аутентификации
текущего сеанса и предоставляет страницу регистрации для
неаутентифицированных пользователейLoginName - элемент управления, который
в заданном формате
отображает имя только того пользователя, который
успешно прошел регистрациюCreateUserWizard - предоставляет многошаговый
пользовательский интерфейс для ввода имени, пароля, контрольных
вопроса и ответа, адреса элекстронной почты, необходимых
при регистрации на сайтеChangePassword - предоставляет пользовательский
интерфейс для смены пароляВсе эти элементы управления по умолчанию настроены на работу
с API Membership.
Этот элемент используется в страницах регистрации и предоставляет
для этого весь необходимый интерфейс. С помощью свойств элемента Login можно настраивать стили, задавать необходимые
надписи и подсказки. Разработаем страницу регистрации с применением
библиотечного элемента управления Login.
Файлы к лабораторной работе Вы можете скачать здесь.
Безопасность включает в себя ряд мероприятий, необходимых
для предотвращения несанкционированного доступа к сайту и защиты
информации. Сюда входят аутентификация (распознавание) и
Основные задачи по защите сайта следующие:
Аутентификация нового пользователя начинается с его регистрации.
Пользователю предлагается страница регистрации с текстовыми
полями, через которую у него запрашиваются некоторые идентификационные
данные. По этим данным создается и сохраняется
Теперь при запросе ограниченного ресурса пользователь предъявит свое удостоверение, которое система верифицирует и примет решение: если удостоверение пользователя подтверждается, ему предоставляется доступ к Web-ресурсу, иначе будет предложена регистрация. Процесс аутентификации может выглядеть примерно так

В приложениях ASP.NET аутентификация может быть реализована одним из следующих способов:
System.Web.Security.FormsAuthenticationModuleSystem.Web.Security.WindowsAuthenticationModuleSystem.Web.Security.PassportAuthenticationModuleСистемы коммуникации шифруются с помощью системы
Обычно сервер, которому клиент собирается пересылать важные
данные, маркируется сертификатом. Сертификат - это некоторый
паспорт сервера, подтверждающий тот факт, что ему можно доверять.
Организация, которой принадлежит сервер, приобретает сертификат
у известного
Наиболее популярными центрами
Инсталированный на
Клиент (
Аутентификация (распознавание) на основе форм реализуется
в пространстве имен System.Web.Security классами:
FormsAuthenticationModuleFormsAuthenticationFormsAuthenticationEventArgs FormsAuthenticationTicketFormsIdentityВыбор
этого режима устанавливается только в одном единственном
месте -
<
Аутентификацию форм можно выполнять и с помощью API-интерфейсов Membership и Roles (об этом
позже).
Аутентификация форм основана на удостоверениях (
Для реализации аутентификации форм нужно выполнить следующее:
В файле web.config виртуального корневого каталога сайта необходимо
определить нужные параметры аутентификации, как свойства класса System.Web.Configuration.FormsAuthenticationConfiguration,
из следующего набора:
| Опция | Значение по умолчанию | Описание |
|---|---|---|
Name |
.ASPXAUTH |
Имя |
LoginUrl |
login.aspx |
Определяет страницу регистрации пользователя
при запросе защищенной страницы (login - |
|
30 |
Время жизни |
SlidingExpiration |
false |
Включает режим скользящего устаревания |
Cookieless |
UseDeviceProfile |
Указывает способ пересылки удостоверения пользователя |
Protection |
All |
Задает уровень безопасности None - не
шифровать и не подписывать - только шифровать - только подписыватьAll - шифровать и подписывать |
RequireSSL |
false |
При включении требует передачи через |
EnableCrossAppRedirects |
false |
Разрешает переадресацию между приложениями при использовании аутентификации форм. Оба приложения должны опираться на одно и то же хранилище удостоверений |
DefaultUrl |
default.aspx |
Указывает страницу, на которую направляется пользователь после успешной регистрации, если он напрямую запросил страницу регистрации, указанную в LoginUrl |
Domain |
пусто |
Может указывать |
Path |
/ |
Путь для |
Перечисленные свойства устанавливаются как атрибуты дочернего
дескриптора <forms> секции <.
Вот пример использования полного набора этих атрибутов в файле web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
timeout="20"
slidingExpiration="true"
cookieless="AutoDetect"
protection="All"
requireSSL="false"
enableCrossAppRedirects="false"
defaultUrl="MyDefault.aspx"
domain=""
path="/"
/>
</authentication>
</system.web>
</configuration>
Хоть это и не самый лучший способ хранения удостоверений
пользователей, зато самый простой. Вообще, удостоверения
можно хранить где угодно, только нужно предусмотреть соответствующий
код их сравнения с введенными на странице регистрации данными.
Если удостоверения хранятся в файле web.config,
то их нужно помещать в дочерний для <forms> дескриптор <credentials>.
Вот пример для трех пользователей
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
timeout="20"
slidingExpiration="true"
cookieless="AutoDetect"
protection="All"
requireSSL="false"
enableCrossAppRedirects="false"
defaultUrl="MyDefault.aspx"
domain=""
path="/"
>
<credentials passwordFormat="Clear">
<user name="Admin" password="Root" />
<user name="Petja" password="Xa-xa" />
<user name="Vasja" password="Xo-xo" />
</credentials>
</forms>
</authentication>
</system.web>
</configuration>
Рассмотрим пример <credentials>,
так и программно.
Создайте
пустой проект Web-приложения командой File/New/Web Site с
именем Login
Добавьте
к приложению корневой Website/Add New Item
Заполните
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false">
<credentials passwordFormat="Clear">
<user name="Admin" password="Root" />
<user name="Петя" password="Уфamp;Уф" />
<user name="Вася" password='!$-*?"' />
</credentials>
</forms>
</authentication>
</system.web>
</configuration>
Значение атрибута passwordFormat="Clear" обеспечивает
открытое хранение пользователей в , SHA1 ), использование которых мы рассмотрим чуть позже.
Добавьте
к проекту командой Website/Add New Item страницу без отделенного
кода с именем LoginAddUsers.aspx по
следующему шаблону
Заполните
страницу LoginAddUsers.aspx следующим кодом<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Configuration" %>
<script runat="server">
protected void btnAddUsers_Click(object sender, EventArgs e)
{
// Учетные записи для новых аутентифицированных пользователей
string[,] authUsers = {
{"user1", "password1"},
{"user2", "password2"},
{"user3", "password3"}
};
// Загрузить содержимое корневого Web.config
Configuration myConfig = System.Web.Configuration.
WebConfigurationManager.OpenWebConfiguration("~/");
// Найти содержимое секции system.web
ConfigurationSectionGroup systemWeb = myConfig.SectionGroups["system.web"];
// Найти содержимое секции authentication
System.Web.Configuration.AuthenticationSection authSec =
(System.Web.Configuration.AuthenticationSection)
systemWeb.Sections["authentication"];
// Установить параметр passwordFormat (Clear, MD5, SHA1)
authSec.Forms.Credentials.PasswordFormat = System.Web.Configuration.FormsAuthPasswordFormat.Clear;
// Добавить новых пользователей
for (int i = 0; i < authUsers.Length / 2; i++)
authSec.Forms.Credentials.Users.Add(new System.Web.Configuration.FormsAuthenticationUser(
authUsers[i, 0], authUsers[i, 1]));
// Обновить файл Web.config
myConfig.Save();
// Отсылаем сообщение
lblUsersResult.Text = "Новые пользователи добавлены!!!";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>Административная страница добавления учетных записей в Web.config</h1>
<p>
<asp:Button ID="btnAddUsers" runat="server" Text="Добавить" OnClick="btnAddUsers_Click" /></p>
<p>
<asp:Label ID="lblUsersResult" runat="server"></asp:Label></p>
</div>
</form>
</body>
</html>
Обратите внимание! Чтобы не использовать полные имена классов вместе с их пространствами имен:
В страницах с отделенным кодом используется инструкция using
В страницах с совмещенным кодом используется директива
<%@ Import Namespace="System.Web.Configuration" %>
В режиме
редактирования страницы LoginAddUsers.aspx выполните
команду File/View in Browser
Откройте
файл Web.config и убедитесь, что
страница LoginAddUsers.aspx при выполнении программно
добавила новых пользователей, а также скорректировала
имена старых пользователей путем приведения символов к нижнему
регистру. Но это несущественно, поскольку ASP.NET при
сравнении имен регистр символов не учитывает<credentials passwordFormat="Clear">
<user name="admin" password="Root" />
<user name="петя" password="Уфamp;Уф" />
<user name="вася" password="!$-*?quot;" />
<user name="user1" password="password1" />
<user name="user2" password="password2" />
<user name="user3" password="password3" />
</credentials>
Добавьте
к проекту две страницы без отделенного кода с именами Default.aspx и MyDefault.aspx со
следующим кодом<%@ Page Language="C#" %>
<script runat="server">
protected void SignOutAction_Click(object sender, EventArgs e)
{
// Уничтожить cookie-набор
FormsAuthentication.SignOut();
// Направить на страницу регистрации
//FormsAuthentication.RedirectToLoginPage();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Страница с ограниченным доступом Default.aspx</h1>
<p>
<asp:Button ID="SignOutAction" runat="server"
Text="Отменить регистрацию" OnClick="SignOutAction_Click" />
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/MyDefault.aspx">На страницу MyDefault.aspx...
</asp:HyperLink></p>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<script runat="server">
protected void SignOutAction_Click(object sender, EventArgs e)
{
// Уничтожить cookie-набор
FormsAuthentication.SignOut();
// Направить на страницу регистрации
//FormsAuthentication.RedirectToLoginPage();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Страница с ограниченным доступом MyDefault.aspx</h1>
<p>
<asp:Button ID="SignOutAction" runat="server"
OnClick="SignOutAction_Click" Text="Отменить регистрацию" />
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/Default.aspx">На страницу Default.aspx...
</asp:HyperLink></p>
</div>
</form>
</body>
</html>
В проводнике
решений вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser . Убедитесь,
что пока ASP.NET разрешает пользоваться
этими страницами без регистрации, т.е. любым
Добавьте
в Окончательный
вид файла Web.config должен стать таким
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false">
<credentials passwordFormat="Clear">
<user name="admin" password="Root" />
<user name="петя" password="Уфamp;Уф" />
<user name="вася" password="!$-*?quot;" />
<user name="user1" password="password1" />
<user name="user2" password="password2" />
<user name="user3" password="password3" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
В проводнике
решений вновь вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser . Убедитесь,
что ASP.NET теперь не разрешает пользоваться
этими страницами loginUrl="MyLogin.aspx"Страница регистрации предоставляет пользователю интерфейс
для ввода имени и пароля, принимает их и сравнивает с удостоверениями,
хранящимися на сервере. Если удостоверения хранятся прямо в
Страница регистрации должна включать в себя поля ввода для
получения от пользователя данных удостоверения. Для проверки
достоверности пользовательских данных необходимо использовать
JavaScript -код
на клиенте, а также выполняющие проверку на сервере.
Создайте
заготовку новой страницы с именем MyLogin.aspx без
отделенного кода
Заполните
страницу элементами управления и настройте их
согласно таблице| Элемент | Свойство | Значение | Пояснение |
|---|---|---|---|
Panel |
ID |
MainPanel |
Родительская панель для оформления рамкой |
BorderColor |
Silver |
Цвет рамки | |
|
|
Тип рамки | |
TextBox |
ID |
UsernameText |
Текстовое поле ввода имени пользователя |
RequiredFieldValidator |
ID |
UsernameRequiredValidator |
Проверка достоверности, чтобы привязанное поле не было пустым |
ControlToValidate |
UsernameText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Не заполнено поле " |
Отображать в элементе ValidationSummary при ошибке | |
|
Пустое поле ввода |
||
Text |
* |
Надпись на визуализированном |
|
RegularExpressionValidator |
ID |
UsernameValidator |
|
ControlToValidate |
UsernameText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Неверное |
Отображать в элементе ValidationSummary при ошибке | |
|
Допустимы буквы, цифры, пробелы и подчеркивания |
||
ValidationExpression |
[а-яА-Я\w| ]* |
[] - диапазон пропускаемых символов[]* - символы диапазона могут встречаться в контролируемом
вводе сколько угодно раза-яА-Я - разрешать все буквы русского алфавита\w - разрешать все латинские буквы, цифры и знаки
подчеркивания. Это | - знак ИЛИ, после которого стоит пробел, означает,
что разрешать и пробелыТаким образом: действительными считаются все русские буквы обоих регистров, все латинские буквы обоих регистров, цифры и знаки подчеркивания, а также пробелы. И все это в любом количестве повторений |
|
Text |
* |
Надпись на визуализированном |
|
TextBox |
ID |
PasswordText |
Текстовое поле ввода пароля |
TextMode |
Password |
Ввод отображается звездочками | |
RequiredFieldValidator |
ID |
PwdRequiredValidator |
Проверка достоверности, чтобы привязанное поле не было пустым |
ControlToValidate |
PasswordText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Не заполнено поле "Пароль" |
Отображать в элементе ValidationSummary при ошибке | |
|
Пустое поле ввода |
||
Text |
* |
Надпись на визуализированном |
|
RegularExpressionValidator |
ID |
PwdValidator |
|
ControlToValidate |
PasswordText |
Привязка к контролируемому элементу ввода | |
Display |
|
Место под элемент выделять только при |
|
ErrorMessage |
Неверный пароль |
Отображать в элементе ValidationSummary при ошибке | |
|
Используются недопустимые символы |
||
ValidationExpression |
[а-яА-Я\w| !"$ |
[] - диапазон пропускаемых символов[]* - символы диапазона могут встречаться в контролируемом
вводе сколько угодно раза-яА-Я - разрешать все буквы русского алфавита\w - разрешать все латинские буквы, цифры и знаки
подчеркивания. Это | - знак ИЛИ, после которого стоит пробел и ряд
других символов, разрешенных для вводаСимволы, которые могут интерпретироваться как служебные,
экранируются обратной косой чертой. Интерпретируемый
HTML-символ амперсанта заменяется неинтерпретируемым
аналогом |
|
Text |
* |
Надпись на визуализированном |
|
Button |
ID |
Button1 |
Кнопка Submit |
Text |
Отправить |
Надпись | |
Label |
ID |
lblResult |
Метка сообщения для заполнения в коде |
ValidationSummary |
ID |
ValidationSummary1 |
Элемент отображения сообщений об ошибках, обнаруженных
|
Интерфейсная часть страницы MyLogin.aspx в режиме проектирования будет такой

Код
страницы MyLogin.aspx будет таким
<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
protected void LoginAction_Click(object sender, EventArgs e)
{
this.Validate();// Исполнить валидаторы на сервере
if (!this.IsValid)// Оценить флаг достоверности
return;// Отправить назад как есть
// Извлечь из web.config и сравнить с введенным
if (FormsAuthentication.Authenticate(UsernameText.Text, PasswordText.Text))
{
// Создать временный cookie-набор (второй параметр false),
// записать в него метку аутентификации и перенаправить
// на исходную запрошенную страницу или MyDefault.aspx
FormsAuthentication.RedirectFromLoginPage(UsernameText.Text, false);
}
else
{
HtmlGenericControl message = new HtmlGenericControl();
message.InnerHtml = "<h2 style='color: Red'>Неверное имя или пароль!</h2>";
form1.Controls.Add(message);
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>Сегодня <% this.Response.Write(DateTime.Now.ToShortDateString()); %> г.</h1>
<h2>
Введите свои имя и пароль</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver"
BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="412px">
<table cellpadding="5" style="width: 100%">
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
Имяnbsp;пользователя:</td>
<td>
nbsp;<asp:TextBox ID="UsernameText" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="UsernameRequiredValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic"
ErrorMessage='Не заполнено поле "Имя пользователя"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="UsernameValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic" ErrorMessage="Неверное имя пользователя"
ToolTip="Допустимы буквы, цифры, пробелы и подчеркивания"
ValidationExpression="[а-яА-Я\w| ]*">*
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
nbsp;Пароль:</td>
<td>
nbsp;<asp:TextBox ID="PasswordText" runat="server"
TextMode="Password" />
</td>
<td>
<asp:RequiredFieldValidator ID="PwdRequiredValidator"
runat="server" ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage='Не заполнено поле "Пароль"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="PwdValidator" runat="server"
ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage="Неверный пароль"
ToolTip="Используются недопустимые символы"
ValidationExpression='[а-яА-Я\w| !"$amp;/()=\-?\*]*'>*
</asp:RegularExpressionValidator>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="Отправить"
OnClick="LoginAction_Click" />
</asp:Panel>
<asp:Label ID="lblResult" runat="server" />
</div>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
</form>
</body>
</html>
В проводнике
решений вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser При такой инфраструктуре аутентификации любой пользователь,
открывший сеанс с приложением, какую бы страницу он не запросил,
будет направляться на страницу регистрации до тех пор, пока
не введет свои данные, хранящиеся в удостоверении конфигурационного
файла. После совпадения удостоверения будет создан -набор
аутентификации со скользящим временем жизни, в котором в зашифрованном
виде будет записан
В нашем файле Web.config до настоящего момента пароли хранились
в виде
В секции <credentials> имеется параметр passwordFormat.
Он предназначен для указания
ASP.NET, в каком формате хранятся значения паролей и какой
алгоритм
Параметр passwordFormat может
принимать одно из трех следующих значений:
Clear - пароль не MD5 - пароль SHA1 - для Для предварительного FormsAuthentication.HashPasswordForStoringInConfigFile().
Добавьте
к проекту страницу HashPasswordPage.aspx с
встроенным скриптом и наполните ее следующим кодом<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Configuration" %>
<script runat="server">
protected void btnHashedPwd_Click(object sender, EventArgs e)
{
// Загрузить содержимое корневого Web.config
Configuration myConfig = System.Web.Configuration.
WebConfigurationManager.OpenWebConfiguration("~/");
// Найти содержимое секции system.web
ConfigurationSectionGroup systemWeb = myConfig.SectionGroups["system.web"];
// Найти содержимое секции authentication
AuthenticationSection authSec =
(AuthenticationSection)
systemWeb.Sections["authentication"];
// Установить параметр passwordFormat, сообщающий, что было хеширование по MD5
authSec.Forms.Credentials.PasswordFormat = FormsAuthPasswordFormat.MD5;
// Извлекаем из коллекции Users старые имена и пароли
int count = authSec.Forms.Credentials.Users.Count;
string[] name = new string[count];
string[] clearTextPwd = new string[count];
int i = 0;
foreach (FormsAuthenticationUser user in authSec.Forms.Credentials.Users)
{
name[i] = user.Name;
clearTextPwd[i] = user.Password;
i++;
}
// Очищаем коллекцию Users
authSec.Forms.Credentials.Users.Clear();
// Добавляем старые имена и новые хешированные пароли
for (i = 0; i < count; i++)
{
// Хешируем исходный пароль
string hashedPwd = FormsAuthentication.
HashPasswordForStoringInConfigFile(clearTextPwd[i], "MD5");
// Добавляем в коллекцию Users
authSec.Forms.Credentials.Users.Add(
new FormsAuthenticationUser(name[i], hashedPwd));
}
// Обновляем файл Web.config
myConfig.Save();
// Отсылаем сообщение
lblHashResult.Text = "Хеширование завершено.<br />"
+ "Повторно не выполнять - будет хеш на хеш!!!";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>
Административная страница хеширования паролей в Web.config</h1>
<p>
<asp:Button ID="btnHashedPwd" runat="server"
OnClick="btnHashedPwd_Click" Text="Хешировать" /></p>
<p>
<asp:Label ID="lblHashResult" runat="server"></asp:Label></p>
</div>
</form>
</body>
</html>
Выполните
страницу HashPasswordPage.aspx,
но только один раз, чтобы повторно не хешировать уже В результате мы получим вариант
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms
name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false"
>
<credentials passwordFormat="MD5">
<user name="admin" password="FA03EB688AD8AA1DB593D33DABD89BAD" />
<user name="петя" password="B63974E3EE7B0920FE24DFB8E82FAE81" />
<user name="вася" password="44D4B2D42E830BE0DD43E6830D957C5D" />
<user name="user1" password="7C6A180B36896A0A8C02787EEAFB0E4C" />
<user name="user2" password="6CB75F652A9B52798EB6CF2201057C73" />
<user name="user3" password="819B0643D6B89DC9B579FDFC9094F28E" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
Откройте
в редакторе оболочки страницу Default.aspx
и командой File/View in Browser запустите
ее на выполнениеВначале будет предложена страница регистрации, поскольку конфигурация сайта настроена именно так.
Введите
в странице регистрации MyLogin.aspx user1 и password1Исходные пароли, вводимые пользователями при регистрации,
остались прежними. Но в
Здесь есть одно
Естественно, что подобная страница
До сих пор мы использовали временные
Постоянные
FormsAuthentication.RedirectFromLoginPage( строка_имя ,
true);
FormsAuthentication.SetAuthCookie( строка_имя ,
true);
HttpCookie authCookie = FormsAuthentication.GetAuthCookie( строка_имя ,
true);
this.Response.
Установленный таким способом
FormsAuthentication.SignOut();
Можно также изменить временной статус постоянного
Добавьте
к проекту страницу ModifyPersistentCookieAuth.aspx без файла отделенного
кода и заполните ее так<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
Label message;
protected void Page_Load(object sender, EventArgs e)
{
// Дескриптор центрирования
HtmlGenericControl center = new HtmlGenericControl("center");
form1.Controls.Add(center);
// Текстовая метка с заголовком
Label label = new Label();
center.Controls.Add(label);
label.Text = "<h2>Закрепить аутентификацию за броузером</h2>";
// Кнопки
Button createPersistentCookie = new Button();
center.Controls.Add(createPersistentCookie);
createPersistentCookie.Text = "Создать бессрочный AuthCookie";
createPersistentCookie.Click += new EventHandler(createPersistentCookie_Click);
center.Controls.Add(new HtmlGenericControl("br"));
Button createTemporaryCookie = new Button();
center.Controls.Add(createTemporaryCookie);
createTemporaryCookie.Text = "Создать срочный AuthCookie";
createTemporaryCookie.Click += new EventHandler(createTemporaryCookie_Click);
center.Controls.Add(new HtmlGenericControl("br"));
Button deleteCookie = new Button();
center.Controls.Add(deleteCookie);
deleteCookie.Text = "Удалить AuthCookie";
deleteCookie.Click += new EventHandler(deleteCookie_Click);
center.Controls.Add(new HtmlGenericControl("br"));
// Текстовая метка с сообщением
message = new Label();
center.Controls.Add(message);
message.Text = String.Empty;
}
void createPersistentCookie_Click(object sender, EventArgs e)
{
// Создать бессрочный cookie
HttpCookie authCookie = FormsAuthentication.GetAuthCookie("xx", true);
// Отослать на броузер
this.Response.Cookies.Add(authCookie);
// Сообщить пользователю
message.Text = "Бессрочный AuthCookie создан!";
}
void createTemporaryCookie_Click(object sender, EventArgs e)
{
// Создать вначале бессрочный cookie
HttpCookie authCookie = FormsAuthentication.GetAuthCookie("xx", true);
// Настроить его как временный сроком на 10 дней
authCookie.Expires = DateTime.Now.AddDays(10);
// Отослать на броузер
this.Response.Cookies.Add(authCookie);
// Сообщить пользователю
message.Text = "Срочный AuthCookie создан!";
}
void deleteCookie_Click(object sender, EventArgs e)
{
// Удалить cookie-набор регистрации
FormsAuthentication.SignOut();
// Сообщить пользователю
message.Text = "AuthCookie удален!";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html>
Интерфейс страницы в режиме выполнения будет таким

При закреплении
API Membership является готовым механизмом в ASP.NET,
предназначенным для организации управления аутентификацией
пользователей. Он базируется на аутентификации форм. Единственное отличие,
что хранение пользователей будет осуществляться не в Membership.
Чаще всего к корневому каталогу сайта допускаются все Web.config. Если кто-то запрашивает защищенный ресурс из подкаталога,
система автоматически перенаправляет пользователя на страницу
регистрации.
Для использования API Membership нужно выполнитиь следующие шаги:
SQL Server 2005 создает базу данных и работает
с ней как с отдельным файлом с расширением .mdf.
По умолчанию файлы баз данных размещаются в каталоге
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data
Мы сами можем вручную создать файл базы данных для хранения
удостоверений и добавить в нее таблицы с необходимыми полями.
Но это может несогласоваться с механизмом API Membership,
поскольку он ожидает базу данных определенной структуры. К
тому же нужно будет прописывать в API Membership. Более
простой вариант предусмотрели разработчики Visual Studio
2005, включив поддержку Membership в
утилиту Web Site ( ).
Теперь база данных
нужной структуры для хранения удостоверений будет создана автоматически
при первом запуске
Откройте
файл web.config и удалите из него секцию <credentials> вместе
с внесенными ранее пользователями и временно закомментируйте
секцию 
В результате конфигурационный файл должен стать таким
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms name="MyCookieName"
loginUrl="MyLogin.aspx"
defaultUrl="MyDefault.aspx"
protection="All"
timeout="20"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="AutoDetect"
domain=""
enableCrossAppRedirects="false">
</forms>
</authentication>
<!-- Временно закомментировали, чтобы не требовал регистрации
<authorization>
<deny users="?"/>
</authorization>
-->
</system.web>
</configuration>
Запустите
утилиту WAT командой Website/ASP.NET Configuration и
обратите внимание, как долго она запускаетсяЗамечание. Эта утилита может не запускаться, если абсолютный путь к созданному проекту имеет пробелы или кириллицу. В этом случае переместите проект в другое место файловой системы компьютера.
В панели Solution Explorer щелкните на кнопке Refresh Мы видим, что утилита так долго запускалась
потому, что добавила к проекту каталог App_Data (если
до этого его еще не было) и создала в нем базу данных ASPNETDB.MDF,
готовую для хранения удостоверений и согласованную с API
Membership

В панели Solution Explorer двойным щелчком на файле ASPNETDB.MDF откройте
соединение с этой базой данных и ознакомтесь в панели Server
Explorer с ее структурой, типичной для SQL
Server
Такой способ хранения удостоверений пользователей в локальной
базе данных вместе с приложением очень удобен, поскольку позволяет
перемещать сайт в любое место сервера или разворачивать на
любом сервере без дополнительных настроек подключения SQL
Server.
Да и создала
такой, какая нужна системе API Membership.
Это значит, что все классы Membership будут
согласованы с хранилищем удостоверений.
Утилита автоматически создает хранилище
удостоверений только в том случае, если обнаружит в корневом
<
Если на момент запуска утилиты файл конфигурации в корневом
каталоге приложения отсутствует или в нем нет секции аутентификации
на основе форм, то утилита базу данных не создает.
Для того, чтобы проверить работоспособность созданной локальной базы данных, выполните следующее:
Запустите
утилиту WAT командой Website/ASP.NET Configuration
На
вкладке Home щелкните на гиперссылке Provider
Configuration, чтобы перейти на вкладку Provider
На
вкладке Provider щелкните на первой гиперссылке
" Select
a single provider for all site management data "
В отклике,
сгенерированном административной страницей ManageConsolidatedProviders.aspx,
щелкните на гиперссылке Test
В результате страница пришлет ответ, что созданная нами локальная база данных функционирует нормально.
Важно отметить, что хоть утилита автоматически
создала базу данных для поддержки именно Membership.
На данном этапе мы рассмотрим интерактивный способ добавления
пользователей с применением утилиты . В дальнейшем можно
будет создать свои административные страницы для программного
добавления пользователей в это хранилище, используя классы Membership. При этом нужно помнить, что хранилище удостоверений
будет размещаться на удаленном сервере и поддерживать его мы
будем как удаленные пользователи либо через , либо через
собственные административные страницы, также хранящиеся на
сервере.
Для создания новых аутентифицированных пользователей через
утилиту выполните следующее:
В панели Solution Explorer щелкните на пиктограмме ASP.NET
Configuration, чтобы запустить утилиту WAT
Перейдите
на вкладку Security и щелкните на гиперссылке Create
userПоявится следующий отклик утилиты

Сообщение на странице предлагает ввести
В утилите за полем ввода пароля закреплен Membership,
которые, в том числе, будут влиять и на поведение .
Заполните
поля страницы для добавления в хранилище одного пользователя
со следующими характеристикамиUser Name: |
|
Password: |
RootRoot |
: |
RootRoot |
E-mail: |
|
Security : |
У Вас продается славянский шкаф? |
Security : |
Шкаф уже продан, осталась только тумбочка! |
и щелкните на кнопке Create User
После этого действия новый пользователь будет создан в базе данных.
В появившемся
отклике щелкните на кнопке Continue , чтобы
вернутся к интерфейсу добавления следующего пользователя,
либо закройте WAT На данном этапе для проверки аутентификации с использованием API Membership и хранилища БД мы воспользуемся
страницей регистрации MyLogin.aspx.
Ее нужно только немного модифицировать.
Модифицируйте
страницу регистрации MyLogin.aspx,
чтобы код стал таким<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
protected void LoginAction_Click(object sender, EventArgs e)
{
this.Validate();// Исполнить валидаторы на сервере
if (!this.IsValid)// Оценить флаг достоверности
return;// Отправить назад как есть
// Извлечь из базы данных и сравнить с введенным
if (Membership.ValidateUser(UsernameText.Text, PasswordText.Text))
{
// Создать временный cookie-набор (второй параметр false),
// записать в него метку аутентификации и перенаправить
// на исходную запрошенную страницу или defaultUrl="MyDefault.aspx"
// с созданием coockie-набора только на период сеанса
FormsAuthentication.RedirectFromLoginPage(UsernameText.Text, false);
}
else
{
HtmlGenericControl message = new HtmlGenericControl();
message.InnerHtml = "<h2 style='color: Red'>Неверное имя или пароль!</h2>";
form1.Controls.Add(message);
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h1>Сегодня <% this.Response.Write(DateTime.Now.ToShortDateString()); %> г.</h1>
<h2>
Введите свои имя и пароль</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver"
BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="412px">
<table cellpadding="5" style="width: 100%">
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
Имяnbsp;пользователя:</td>
<td>
nbsp;<asp:TextBox ID="UsernameText" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="UsernameRequiredValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic"
ErrorMessage='Не заполнено поле "Имя пользователя"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="UsernameValidator"
runat="server" ControlToValidate="UsernameText"
Display="Dynamic" ErrorMessage="Неверное имя пользователя"
ToolTip="Допустимы буквы, цифры, пробелы и подчеркивания"
ValidationExpression="[а-яА-Я\w| ]*">*
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 167px">
nbsp;Пароль:</td>
<td>
nbsp;<asp:TextBox ID="PasswordText" runat="server"
TextMode="Password" />
</td>
<td>
<asp:RequiredFieldValidator ID="PwdRequiredValidator"
runat="server" ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage='Не заполнено поле "Пароль"'
ToolTip="Пустое поле ввода">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="PwdValidator" runat="server"
ControlToValidate="PasswordText"
Display="Dynamic" ErrorMessage="Неверный пароль"
ToolTip="Используются недопустимые символы"
ValidationExpression='[а-яА-Я\w| !"$amp;/()=\-?\*]*'>*
</asp:RegularExpressionValidator>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="Отправить"
OnClick="LoginAction_Click" />
</asp:Panel>
<asp:Label ID="lblResult" runat="server" />
</div>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
</form>
</body>
</html>
Запустите
приложение с любой страницы и введите User
Name: |
|
Password: |
RootRoot |
С помощью
утилиты WAT добавьте в хранилище еще несколько пользователей
и убедитесь, что аутентификация на основе Membership и хранилища
удостоверений в БД работаетПри добавлении новых пользователей следует иметь ввиду, что
реляционной
таблицы aspnet_Users и
является основой для формирования поля как
В панели Server Explorer установите соединение с
базой данных ASPNETDB двойным щелчком указателя
мыши на пиктограмме базы
Для
таблиц aspnet_Users и aspnet_Membership выполните
команду Show Table Data контекстного меню
После таких действий откроются таблицы aspnet_Users и aspnet_Membership,
в которых можно найти информацию о созданных пользователях.
Для того, чтобы увидеть структуру таблиц, следует выполнить
для них команду Open Table контекстного меню.
Интерфейс API Membership включает в себя
следующие классы пространства имен System.Web.Security:
Membership - статический класс, имеющий ряд полезных методов
MembershipCreateUserException - исключение,
генерируемое ошибкой MembershipPasswordException - исключение при невозможности
извлечения пароляMembershipUser - объект этого класса содержит всю информацию
о пользователе и возвращается методом Membership.GetUser()MembershipUserCollection - коллекция пользователей,
извлекаемая методом Membership.GetAllUsers()MembershipProvider - базовый класс для MembershipProviderCollection - коллекция доступных для
приложения поставщиков на данной машинеSqlMembershipProvider - поставщик для работы с базами данных
SQL ServerActiveDirectoryMembershipProvider - поставщик для работы
со службой ActiveDirectoryMembershipUser - класс поддержки пользователя,
расширенный для работы со службой Используя API Membership, можно программно решать, например,
следующие задачи:
Для создания и удаления пользователей следует применить перегруженные
статические методы CreateUser() и класса Membership.
Нужно создать административные страницы, содержащие требуемые
поля для ввода информации. Поля можно контролировать
Метод CreateUser() имеет несколько перегрузок,
из которых простейшая принимает только имя и пароль. В то же
время более полные CreateUser() содержит экземпляр
перечисления MembershipCreateStatus в качестве
CreateUser(), включающую контрольный
вопрос и ответ, чтобы избежать выброса исключения MembershipCreateUserException.
Удаление пользователя выполняется методом Membership.,
которому передается в качестве параметра уникальное
В качестве примера создадим собственную страницу добавления,
имеющую аналогичную функциональность с , и
отдельно страницу удаления пользователя в БД. Для простоты
эти страницы мы переделаем из страницы регистрации MyLogin.aspx.
Скопируйте
страницу MyLogin.aspx и присвойте копии
имя AddUserMembership.aspxCustomValidator.
С помощью этого элемента реализуем проверку достоверности на
клиенте и на сервере.
Неалфавитно-цифровые символы представим
в виде -кодов согласно следующей таблице
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ||||||||||
| 1 | ||||||||||
| 2 | ||||||||||
| 3 | ! | " | # | $ | % | ' | ||||
| 4 | ( | ) | * | + | , | . | / | |||
| 5 | : | ; | ||||||||
| 6 | < | = | > | ? | @ | |||||
| 7 | ||||||||||
| 8 | ||||||||||
| 9 | [ | \ | ] | ^ | _ | |||||
| 10 | ||||||||||
| 11 | ||||||||||
| 12 | { | | | } | ~ |
Строка -кодов неалфавитно-цифровых символов на JavaScript будет такой:
var nonAlphanumericCharactersString = String.fromCharCode(33,34,35,36,37,38,39,40,41,42,43,44,45,46,
58,59,60,61,62,63,64,91,92,93,94,95,123,124,125,126);
Переделайте
интерфейсную и скриптовую части страницы, чтобы она стала
такой<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
// Блок на C# по умолчанию
protected void Page_Load(object sender, EventArgs e)
{
// Вынесли из интерфейсной части из-за большой ширины листинга
passwordValidator.ErrorMessage =
"Пароль должен иметь длину не менее 7 символов"
+ " и содержать хотя бы один неалфавитно-цифровой символ";
}
protected void AddUserMembership_Click(object sender, EventArgs e)
{
this.Validate();// Исполнить валидаторы на сервере
if (!this.IsValid)// Оценить флаг достоверности
return;// Отправить назад как есть
// Создаем экземпляр перечисления
MembershipCreateStatus status;
// Попытка добавить
try
{
Membership.CreateUser(
username.Text,
password.Text,
email.Text,
question.Text,
answer.Text,
true,
out status
);
lblResult.Text = String.Empty;
switch (status)
{
case MembershipCreateStatus.DuplicateUserName:
lblResult.Text = "Дублированное имя пользователя<br/>";
goto default;
case MembershipCreateStatus.ProviderError:
lblResult.Text = "Ошибка Поставщика<br/>";
goto default;
default: // Дальше лень анализировать
lblResult.Text += "Пользователь не создан";
lblResult.ForeColor = System.Drawing.Color.Red;
break;
case MembershipCreateStatus.Success:
// Выдаем успешную информацию
lblResult.Text = "Пользователь " + username.Text
+ " создан успешно!";
// Рекурсивно очищаем все текстовые поля ввода
EmptyTextBox(form1.Controls);
lblResult.Text += "<br/>Поля ввода очищены";
break;
}
}
// Откат
catch (MembershipCreateUserException ex)
{
lblResult.Text = "<h2 style='color: Red'>Ошибка создания пользователя</h2>";
System.Diagnostics.Debug.WriteLine("Exception: "
+ ex.Message);
}
}
private void EmptyTextBox(ControlCollection controls)
{
foreach (Control ctrl in controls)
{
if (ctrl is TextBox)
((TextBox)ctrl).Text = String.Empty;
// Идем в глубину иерархической цепочки и ищем дочерние элементы
if (ctrl.Controls != null)
EmptyTextBox(ctrl.Controls);
}
}
</script>
<script language="C#" runat="server">
// Еще один блок с явным указанием C#, хотя можно атрибут языка и не указывать
// Проверка допустимости пароля на сервере
// Обработчик события ServerValidate элемента CustomValidator
protected void passwordValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
string data = args.Value;
// Установить начальное значение флага достоверности
args.IsValid = false;
// Проверить длину пароля
if (data.Length < 7)
return;
// Проверить наличие неалфавитноцифрового символа
// Формируем массив неалфавитноцифровых символов по их кодам,
// чтобы не связываться с интерпретируемыми символами
int[] nonAlphanumericCharactersCode =
{33,34,35,36,37,38,39,40,41,42,43,44,45,46,
58,59,60,61,62,63,64,91,92,93,94,95,123,124,125,126};
// Перебираем символы пользовательского ввода
foreach (char ch in data)
{
for (int i = 0; i < nonAlphanumericCharactersCode.Length; i++)
if (ch == Convert.ToChar(nonAlphanumericCharactersCode[i]))
{
// Пароль допустим
args.IsValid = true;
return;
}
}
}
</script>
<script language="javascript" type="text/javascript">
// Проверка допустимости пароля на клиенте. Работает при включенном
// по умолчанию свойстве EnableClientScript элемента CustomValidator
function ValidatePassword(source, args)
{
// Расщепить строку на массив символов с пустым разделителем
var data = args.Value.split("");
// Установить начальное значение флага достоверности
args.IsValid = false;
// Проверить длину пароля
if(data.length < 7)
return;
// Проверить наличие неалфавитноцифрового символа
// Формируем строку неалфавитноцифровых символов по их кодам,
// чтобы не связываться с интерпретируемыми символами
var nonAlphanumericCharactersString =
String.fromCharCode(33,34,35,36,37,38,39,40,41,42,43,44,45,46,
58,59,60,61,62,63,64,91,92,93,94,95,123,124,125,126);
for(var ch in data)
{
if(nonAlphanumericCharactersString.indexOf(data[ch]) != -1)
{
// Пароль допустим
args.IsValid = true;
return;
}
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Добавление пользователей в БД</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h2 id="H2_1" runat="server">
Введите учетную запись для добавления пользователя</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver" BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="364px">
<table cellpadding="5" style="width: 137%">
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
Имяnbsp;пользователя:
</td>
<td>
nbsp;<asp:TextBox ID="username" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="usernameRequiredValidator"
runat="server" ControlToValidate="username"
ErrorMessage='Не заполнено поле "Имя пользователя"'
Display="Dynamic">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
nbsp;Пароль:
</td>
<td>
nbsp;<asp:TextBox ID="password" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="passwordRequiredValidator"
runat="server" ControlToValidate="password"
ErrorMessage='Не заполнено поле "Пароль"'
Display="Dynamic">*</asp:RequiredFieldValidator>
<asp:CustomValidator ID="passwordValidator" runat="server"
ControlToValidate="password"
Display="Dynamic"
ClientValidationFunction="ValidatePassword"
OnServerValidate="passwordValidator_ServerValidate">*</asp:CustomValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
E-mail:</td>
<td>
nbsp;<asp:TextBox ID="email" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="emailRequiredValidator"
runat="server" ControlToValidate="email"
ErrorMessage='Не заполнено поле "E-mail"'
Display="Dynamic">*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="emailValidator" runat="server"
ControlToValidate="email" ErrorMessage="Неверный E-mail"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
Display="Dynamic">*</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
Контрольный вопрос:</td>
<td>
nbsp;<asp:TextBox ID="question" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="questionRequiredValidator"
runat="server" ControlToValidate="question"
ErrorMessage='Не заполнено поле "Контрольный вопрос"'
Display="Dynamic">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
nbsp;nbsp;nbsp;
</td>
<td align="right" height="43" style="width: 224px">
Контрольный ответ:</td>
<td>
nbsp;<asp:TextBox ID="answer" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="answerRequiredValidator"
runat="server" ControlToValidate="answer"
ErrorMessage='Не заполнено поле "Контрольный ответ"'
Display="Dynamic">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td colspan="4" align="center">
<asp:Button ID="btnAddUser" runat="server"
Text="Добавить" OnClick="AddUserMembership_Click" />
</td>
</tr>
</table>
</asp:Panel>
<asp:Label ID="lblResult" runat="server" Font-Bold="True"
Font-Size="Large" ForeColor="Blue" />
</div>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
</form>
</body>
</html>
Выполните
страницу AddUserMembership.aspx и убедитесь
в работоспособности рассматриваемого механизма добавления
пользователей в БД SQL ServerТеперь рассмотрим вопрос удаления пользователей. Он намного
проще, чем создание. Нужно только применить метод System.Web.Security.Membership.,
который имеет две
public static bool DeleteUser ( string
username ) - удаляет
по имени пользователя все связанные с ним данные из
всех таблиц БДpublic static bool DeleteUser ( string
username , bool deleteAllRelatedData ) - удаляет пользователя
только из таблицы aspnet_Users,
если флаг равен false. Иначе удаляет все
связанные с пользователем данные при флаге равном trueОбе true, если пользователь успешно
удален, иначе false.
Разработайте
из копии страницы MyLogin.aspx административную
страницу удаления пользователей DeleteUserMembership.aspx, которая будет примерно
такой<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
protected void DeleteUser_Click(object sender, EventArgs e)
{
if (Membership.DeleteUser(username.Text))
{
lblResult.Text="Пользователь " + username.Text
+ " успешно удален";
username.Text = "";
}
else
{
lblResult.Text = "Пользователь не удален";
lblResult.ForeColor = System.Drawing.Color.Red;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Удаление пользователей из БД</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h2>
Введите имя удаляемого пользователя</h2>
<asp:Panel ID="MainPanel" runat="server" BorderColor="Silver"
BorderStyle="Ridge"
BorderWidth="2px" Height="90px" Width="412px">
<table cellpadding="5" style="width: 100%">
<tr>
<td align="right" height="43" style="width: 167px">
Имяnbsp;пользователя:</td>
<td>
nbsp;<asp:TextBox ID="username" runat="server" />
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="Удалить"
OnClick="DeleteUser_Click" /></asp:Panel>
<asp:Label ID="lblResult" runat="server" Font-Bold="True"
Font-Size="Large" ForeColor="Blue">
</asp:Label>
</div>
</form>
</body>
</html>
Испытайте
страницу удаления пользователейДля получения списка пользователей применяют метод Membership.GetAllUsers(),
а для извлечения конкретного пользователя - метод Membership.GetUser().
Рассмотрим пример, в котором будем использовать элемент для представления пользователей в виде таблицы.
Добавьте
к проекту страницу GetUsersMembership.aspx без
файла отделенного кода и назначьте ее стартовой
Заполните
страницу следующим кодом<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
// Вынесли поле класса для видимости в обработчиках
MembershipUserCollection myUsers = new MembershipUserCollection();
protected void Page_Load(object sender, EventArgs e)
{
// Скрываем таблицу деталей
tableDetails.Visible = false;
lblUser.Visible = false;
if (checkUser.Checked)
{
// Извлекаем одного пользователя
if (txtUser.Text.Length == 0)
{
lblUsersList.Text = "Введите имя пользователя";
return;
}
try // Попытка
{
string user = Server.HtmlEncode(txtUser.Text);
myUsers = new MembershipUserCollection();
myUsers.Add(Membership.GetUser(user));
}
catch // Откат
{
lblUsersList.Text = "Пользователь не найден";
return;
}
}
else
{
// Извлекаем всех пользователей
myUsers = Membership.GetAllUsers();
}
// Подключаем к сетке извлеченную информации и наполняем элемент
UsersGridView.DataSource = myUsers;
UsersGridView.DataBind();
}
// Обработчик щелчков на ссылки столбца отображения деталей
protected void UsersGridView_SelectedIndexChanged(object sender, EventArgs e)
{
if (UsersGridView.SelectedIndex >= 0)
{
// Заполняем интерфейсные элементы отображаемой информацией,
// адресуясь к конкретному пользователю по ключевому имени,
// заданному параметром DataKeyNames="UserName" элемента GridView
MembershipUser currentUser =
myUsers[(string)UsersGridView.SelectedValue];
lblUserName.Text = currentUser.UserName;
lblEmail.Text = currentUser.Email;
lblPasswordQuestion.Text = currentUser.PasswordQuestion;
lblLastLoginDate.Text = currentUser.LastLoginDate.ToLongDateString();
txtComment.Text = currentUser.Comment;
checkIsApproved.Checked = currentUser.IsApproved;
checkIsLockedOut.Checked = currentUser.IsLockedOut;
// Включаем видимость таблицы деталей
tableDetails.Visible = true;
lblUser.Visible = true;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>
<asp:Label ID="lblUsersList" runat="server" Font-Bold="true"
Text="Список зарегистрированных пользователей"></asp:Label>
</h2>
<p>Конкретный пользователь:
<asp:CheckBox ID="checkUser" runat="server" />
<asp:TextBox ID="txtUser" runat="server"></asp:TextBox>
<asp:Button ID="btnUser" runat="server" Text="Получить" /></p>
<asp:GridView ID="UsersGridView" runat="server"
DataKeyNames="UserName"
AutoGenerateColumns="False"
OnSelectedIndexChanged="UsersGridView_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="UserName" HeaderText="Имя" />
<asp:BoundField DataField="Email" HeaderText="email" />
<asp:BoundField DataField="CreationDate" HeaderText="Создан" />
<asp:CommandField ShowSelectButton="True" HeaderText="Детали"
SelectText="Показать" />
</Columns>
</asp:GridView>
<h2>
<asp:Label ID="lblUser" runat="server"
Text="Подробности для выделенного пользователя"
Visible="False" Font-Bold="true"></asp:Label>
</h2>
<table id="tableDetails" bordercolor="#0000FF"
runat="server">
<tr>
<td width="50%">
Пользователь:</td>
<td>
<asp:Label ID="lblUserName" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
email:</td>
<td>
<asp:Label ID="lblEmail" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Контрольный вопрос:</td>
<td>
<asp:Label ID="lblPasswordQuestion" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Дата последней регистрации:</td>
<td>
<asp:Label ID="lblLastLoginDate" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Комментарии:</td>
<td>
<asp:TextBox ID="txtComment" runat="server" TextMode="MultiLine"
></asp:TextBox></td>
</tr>
<tr>
<td width="50%">
Проверенный:</td>
<td>
<asp:CheckBox ID="checkIsApproved" runat="server" /></td>
</tr>
<tr>
<td width="50%">
Заблокирован:</td>
<td>
<asp:CheckBox ID="checkIsLockedOut" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Интерфейсная часть страницы представлена элементом и
текстовыми метками, спозиционированными в серверной таблице.
Значения параметров элемента представляют
собой имена полей таблиц aspnet_Users и aspnet_Membership базы
данных

Установка в элементе управления свойства DataKeyNames=" позволяет
извлекать значения поля через ,
что очень удобно при получении подробностей о конкретном пользователе
из коллекции пользователей.
Метод Membership. GetUser() возвращает
объект запрошенного пользователя, свойства которого мы отображаем
в текстовых элементах, скомпонованных в таблице. Привязка
к свойствам объекта пользователя выполняется в обработчике
события SelectedIndexChanged элемента управления .
Результат работы страницы GetUsersMembership.aspx будет
примерно таким

Если у нас есть экземпляр класса MembershipUser, то мы можем обновить его свойства, имеющие аксессор set, а именно:
Comment Email IsApproved LastActivityDate LastLoginDate Для этого используется статический метод Membership. UpdateUser().
Получите из страницы GetUsersMembership.aspx копию с именем UpdateUserMembership.aspx
Скорректируйте страницу UpdateUserMembership.aspx, чтобы обновляемые параметры таблицы деталей размещались в текстовых полях
Закрепите за полем txtEmail элементы проверки достоверности RequiredFieldValidator и RegularExpressionValidatorОкончательный код страницы UpdateUserMembership.aspx будет таким
<%@ Page Language="C#" EnableViewState="false" %>
<%@ Import Namespace="System.Web.Security" %>
<script runat="server">
// Вынесли поле для видимости в обработчиках
MembershipUserCollection myUsers = new MembershipUserCollection();
protected void Page_Load(object sender, EventArgs e)
{
// Скрываем таблицу деталей
tableDetails.Visible = false;
lblUser.Visible = false;
// Извлекаем всех пользователей
myUsers = Membership.GetAllUsers();
// Подключаем к сетке извлеченную информации и наполняем элемент
UsersGridView.DataSource = myUsers;
UsersGridView.DataBind();
}
// Обработчик щелчков на ссылки столбца отображения деталей
protected void UsersGridView_SelectedIndexChanged(object sender, EventArgs e)
{
if (UsersGridView.SelectedIndex >= 0)
{
// Заполняем интерфейсные элементы отображаемой информацией,
// адресуясь к конкретному пользователю по ключевому имени,
// заданному параметром DataKeyNames="UserName" элемента GridView
MembershipUser currentUser =
myUsers[(string)UsersGridView.SelectedValue];
lblUserName.Text = currentUser.UserName;
txtEmail.Text = currentUser.Email;
lblPasswordQuestion.Text = currentUser.PasswordQuestion;
lblLastLoginDate.Text = currentUser.LastLoginDate.ToLongDateString();
txtComment.Text = currentUser.Comment;
checkIsApproved.Checked = currentUser.IsApproved;
checkIsLockedOut.Checked = currentUser.IsLockedOut;
// Включаем видимость таблицы деталей
tableDetails.Visible = true;
lblUser.Visible = true;
}
}
protected void btnUpdate_Click(object sender, EventArgs e)
{
if (UsersGridView.SelectedIndex >= 0)
{
// Адресуемся к выделенному пользователю
MembershipUser currentUser =
myUsers[(string)UsersGridView.SelectedValue];
// Избавляемся от возможных управляющих символов
// в пользовательском вводе
currentUser.Email = Server.HtmlEncode(txtEmail.Text);
currentUser.Comment = Server.HtmlEncode(txtComment.Text);
currentUser.IsApproved = checkIsApproved.Checked;
// Сбрасываем в базу данных
Membership.UpdateUser(currentUser);
// Обновить содержимое GridView из БД, поскольку
// этот обработчик выполнится после Page_Load
myUsers = Membership.GetAllUsers();// Извлекаем пользователей
UsersGridView.DataBind();
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>
<asp:Label ID="lblUsersList" runat="server" Font-Bold="true"
Text="Список зарегистрированных пользователей"></asp:Label>
</h2>
<asp:GridView ID="UsersGridView" runat="server"
DataKeyNames="UserName"
AutoGenerateColumns="False"
OnSelectedIndexChanged="UsersGridView_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="UserName" HeaderText="Имя" />
<asp:BoundField DataField="Email" HeaderText="email" />
<asp:BoundField DataField="CreationDate" HeaderText="Создан" />
<asp:CommandField ShowSelectButton="True" HeaderText="Детали"
SelectText="Показать" />
</Columns>
</asp:GridView>
<h2>
<asp:Label ID="lblUser" runat="server"
Text="Подробности для выделенного пользователя"
Visible="False" Font-Bold="true"></asp:Label>
</h2>
<table id="tableDetails" bordercolor="#0000FF"
runat="server">
<tr>
<td width="50%">
Пользователь:</td>
<td>
<asp:Label ID="lblUserName" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
<font>email:</font></td>
<td>
<asp:TextBox ID="txtEmail" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator
ID="RequiredFieldValidator1" runat="server"
ControlToValidate="txtEmail" Display="Dynamic">*
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1"
runat="server" ControlToValidate="txtEmail"
Display="Dynamic"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
</asp:RegularExpressionValidator></td>
</tr>
<tr>
<td width="50%">
Контрольный вопрос:</td>
<td>
<asp:Label ID="lblPasswordQuestion" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
Дата последней регистрации:</td>
<td>
<asp:Label ID="lblLastLoginDate" runat="server"></asp:Label></td>
</tr>
<tr>
<td width="50%">
<font>Комментарии:</font></td>
<td>
<asp:TextBox ID="txtComment" runat="server" TextMode="MultiLine"
></asp:TextBox></td>
</tr>
<tr>
<td width="50%">
<font>Проверенный:</font></td>
<td>
<asp:CheckBox ID="checkIsApproved" runat="server" /></td>
</tr>
<tr>
<td width="50%">
Заблокирован:</td>
<td>
<asp:CheckBox ID="checkIsLockedOut" runat="server" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<asp:Button ID="btnUpdate" runat="server" Text="Обновить"
OnClick="btnUpdate_Click" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Вкладка Login панели Toolbox содержит
компоненты, которые обеспечивают пользовательский интерфейс
и функциональность для выполнения большинства типовых операций
членства и безопасности.

Это следующие компоненты:
Login - предоставляет два поля для ввода
имени пользователя и пароля, а также кнопку для отправки
на проверку удостоверения пользователя. По умолчанию проверка
выполняется через API MembershipLoginView - позволяет отображать разные
наборы элементов управления для разных категорий пользователейPasswordRecovery - предоставляет необходимый
интерфейс для запроса контрольного ответа и обеспечивает
повторную отправку пользователю утраченного пароля через
электронную почтуLoginStatus - проверяет состояние аутентификации
текущего сеанса и предоставляет страницу регистрации для
неаутентифицированных пользователейLoginName - элемент управления, который
в заданном формате
отображает имя только того пользователя, который
успешно прошел регистрациюCreateUserWizard - предоставляет многошаговый
пользовательский интерфейс для ввода имени, пароля, контрольных
вопроса и ответа, адреса элекстронной почты, необходимых
при регистрации на сайтеChangePassword - предоставляет пользовательский
интерфейс для смены пароляВсе эти элементы управления по умолчанию настроены на работу
с API Membership.
Этот элемент используется в страницах регистрации и предоставляет
для этого весь необходимый интерфейс. С помощью свойств элемента Login можно настраивать стили, задавать необходимые
надписи и подсказки. Разработаем страницу регистрации с применением
библиотечного элемента управления Login.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.