Безопасность: аутентификация с помощью форм
Программное добавление пользователей в конфигурационный файл
-
Добавьте
к проекту командой 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>
Листинг
37.4.
Страница LoginAddUsers.aspx
Обратите внимание! Чтобы не использовать полные имена классов вместе с их пространствами имен:
В страницах с отделенным кодом используется инструкция 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="Уф&Уф" />
<user name="вася" password="!$-*?"" />
<user name="user1" password="password1" />
<user name="user2" password="password2" />
<user name="user3" password="password3" />
</credentials>
Листинг
37.5.
Секция <credentials> файла Web.config после выполнения страницы
-
Добавьте
к проекту две страницы без отделенного кода с именами 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>
Листинг
37.6.
Страница Default.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 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>
Листинг
37.7.
Страница MyDefault.aspx
-
В проводнике
решений вызовите контекстное меню для страницы 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="Уф&Уф" />
<user name="вася" password="!$-*?"" />
<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>
Листинг
37.8.
Добавление требования регистрации в файл Web.config
-
В проводнике
решений вновь вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser. Убедитесь,
что ASP.NET теперь не разрешает пользоваться
этими страницами анонимно и пытается адресоваться к странице
регистрации, назначенной нами в конфигурационном файле параметром loginUrl="MyLogin.aspx"
Создание страницы регистрации
Страница регистрации предоставляет пользователю интерфейс для ввода имени и пароля, принимает их и сравнивает с удостоверениями, хранящимися на сервере. Если удостоверения хранятся прямо в конфигурационном файле, их извлечение и проверка достаточно просты. Не намного сложнее извлекать удостоверения, хранящиеся в любом другом внешнем хранилище - файле или базе данных.
Страница регистрации должна включать в себя поля ввода для получения от пользователя данных удостоверения. Для проверки достоверности пользовательских данных необходимо использовать валидаторы, генерирующие нужный JavaScript -код на клиенте, а также выполняющие проверку на сервере.
-
Создайте
заготовку новой страницы с именем MyLogin.aspx без
отделенного кода -
Заполните
страницу элементами управления и настройте их
согласно таблице
Интерфейсная часть страницы 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>
</td>
<td align="right" height="43" style="width: 167px">
Имя пользователя:</td>
<td>
<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>
</td>
<td align="right" height="43" style="width: 167px">
Пароль:</td>
<td>
<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| !"$&/()=\-?\*]*'>*
</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>
Листинг
37.9.
Код страницы регистрации MyLogin.aspx
-
В проводнике
решений вызовите контекстное меню для страницы Default.aspx или MyDefault.aspx и
выполните команду View in Browser
При такой инфраструктуре аутентификации любой пользователь, открывший сеанс с приложением, какую бы страницу он не запросил, будет направляться на страницу регистрации до тех пор, пока не введет свои данные, хранящиеся в удостоверении конфигурационного файла. После совпадения удостоверения будет создан cookie -набор аутентификации со скользящим временем жизни, в котором в зашифрованном виде будет записан мандат, и этот мандат будет действовать на протяжении всего сеанса, пока не истечет допустимое временя простоя сеанса или пока cookie-набор аутентификации не будет нами уничтожен.

