Китай |
Безопасность: аутентификация с помощью форм
Программное добавление пользователей в конфигурационный файл
- Добавьте к проекту командой 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-набор аутентификации не будет нами уничтожен.