Автор: Уиллмов и Хит Стюарт
Домашняя страница: http://www.amuhouse.com
Электронная почта: [email protected]
Примечание. Я только два месяца назад изучил ASP.NET. На сайте codeproject.com я увидел статью под названием «Ролевая безопасность с проверкой подлинности с помощью форм» и нашел ее очень полезной. В то время я хотел перевести это на китайский язык. Однако прямой перевод действительно скучен. В последние два дня я ссылался на эту статью Хита Стюарта и, исходя из собственного понимания, написал ее на китайский язык в соответствии со своими идеями и выражениями. Прилагается демонстрационное веб-приложение, которое я создал для этой статьи.
Если возникло недопонимание, напишите, чтобы указать на это, или оставьте комментарий.
P.S. Спам очень раздражает, пожалуйста, проявите уважение.
Исходная статья находится по адресу http://www.codeproject.com/aspnet/formsroleauth.asp.
Автор оригиналаХит Стюарт
краткое содержание:
ASP.NET предоставляет механизм аутентификации на основе ролей, но его поддержка ролей является неполной. В этой статье делается попытка проиллюстрировать, как реализовать и использовать этот механизм аутентификации на основе ролей, на некоторых примерах.
Введение.
Аутентификация по форме в ASP.NET — это очень мощная функция, требующая лишь небольшого количества кода для реализации простой, независимой от платформы системы аутентификации безопасности.
Однако если вам нужен более сложный и эффективный механизм аутентификации, вам придется воспользоваться его гибкостью, разделив множество пользователей на группы пользователей. Встроенная проверка подлинности Windows предоставляет этот механизм проверки подлинности, но он использует NTLM, диспетчер локальной сети Windows NT, поэтому он не является кроссплатформенным. Сейчас все больше и больше людей используют системы Linux, и появляется все больше и больше пользователей браузера Mozilla Forefox. Мы, конечно, не можем удержать этих людей, поэтому мы ищем другой механизм аутентификации. Есть два варианта: один — разделить веб-сайт на несколько областей и предоставить несколько страниц входа, заставляя пользователей регистрироваться и входить в систему одну за другой, другой — группировать пользователей и ограничивать права доступа определенных групп пользователей к определенной странице; или область. Последнее, безусловно, лучший выбор. Мы можем добиться этой функциональности, назначая роли отдельным пользователям.
Microsoft оставила механизм аутентификации на основе ролей в аутентификации с помощью форм для платформы .NET, но нам придется реализовать его самостоятельно. В этой статье мы стремимся осветить некоторые основные моменты, касающиеся механизма аутентификации на основе ролей в аутентификации с помощью форм, такие как его концепция, его реализация, способы его применения в веб-приложениях и т. д.
Необходимая подготовка:
Сначала нам нужно создать базу данных, проект веб-приложения, несколько конфиденциальных каталогов с разными уровнями безопасности и несколько страниц ASP.NET. Конечно, вы также можете добавить их в существующий проект веб-приложения.
1. Для создания базы данных
необходимо сначала выбрать СУБД системы управления базами данных, которую вы хотите использовать. В этой статье используется SQL Server 2000.
В базе данных реальных проектов приложений обычно имеется таблица пользовательских данных «Пользователи», которая может включать уникальный тег пользователя: UserID, имя пользователя: UserName, пароль: Пароль, адрес электронной почты пользователя: Email, город пользователя: City и номер логины пользователей LoginCount и т. д. Вы можете назначить роли пользователям, создав таблицу данных UserInRoles (обычно включающую два поля: имя пользователя: UserName, роль пользователя: UserRoles).
Для простоты я создаю только таблицу данных «Пользователи», которая имеет 3 поля: имя пользователя «Имя пользователя», пароль «Пароль» и роли пользователя «UserRoles». Перед созданием таблицы необходимо выбрать базу данных или создать новую базу данных. Чтобы создать новую базу данных с именем WebSolution, требуется только простой оператор SQL:
программный код
Создать веб-решение БАЗЫ ДАННЫХ
Чтобы выбрать базу данных с именем msdb
в GO
, вы можете использовать оператор SQL:
программный код
ИСПОЛЬЗОВАТЬ MSDB
ИДТИ
Далее мы создаем только что упомянутую таблицу данных Users. Сценарий SQL выглядит следующим образом:
Программный код
Create TABLE Users.
(
Имя пользователя nvarchar(100) CONSTRAINT PK_Имя пользователя ПЕРВИЧНЫЙ КЛЮЧ,
Пароль nvarchar(150),
Роли пользователя nvarchar(100)
)
может создать учетные данные индекса для этой таблицы. Оператор SQL выглядит следующим образом:
Программный код
Создать учетные данные INDEX ON Users.
(
Имя пользователя,
Пароль
)
Создание индекса не является обязательным и зависит от вас. Пожалуйста, обратитесь к соответствующей информации о преимуществах и недостатках индексации.
Затем мы добавляем данные в эту базу данных пользователей. Имя персонажа вы выбираете сами, но лучше всего использовать осмысленное имя, например:
«Администратор» (администратор верхнего уровня), «Менеджер» (администратор), «Участник» (присоединившийся участник), «Пользователь» (обычный пользователь) и т. д. Например:
Имя пользователя|Пароль|Роли.
"willmove"|"pwd123"|"Администратор,Пользователь"
"amuhouse"|"pwd123"|"User"
:
программный код
--обратите внимание, что "45CB41B32DCFB917CCD8614F1536D6DA" — это строка, зашифрованная md5 с использованием "pwd123".
Вставьте INTO пользователей (имя пользователя, пароль, роли пользователя) ЗНАЧЕНИЯ («willmove», «45CB41B32DCFB917CCD8614F1536D6DA», «Администратор, Пользователь»)
ИДТИ
Вставьте INTO пользователей (имя пользователя, пароль, роли пользователя) ЗНАЧЕНИЯ («amuhouse», «45CB41B32DCFB917CCD8614F1536D6DA», «Пользователь»)
ИДТИ
Обратите внимание, что роли чувствительны к регистру, поскольку они учитываются в файле Web.config. Теперь мы создаем несколько необходимых страниц для реализации этого механизма аутентификации безопасности.
Первая — это страница входа пользователя Login.aspx.
Если вы еще не создали веб-приложение, создайте его сейчас. Конечно, вы также можете создать эту страницу в существующем веб-приложении. Здесь я предполагаю, что создано веб-приложение с именем RolebasedAuth (т. е. проект в Visual Studio .Net). Я поместил этот файл Login.aspx в его корневой каталог, доступный через http://localhost/RolebasedAuth/Login.aspx .
Не имеет значения, где находится этот файл Login.aspx, но он должен быть общедоступным.
В корневом пути приложения мы создаем два секретных подкаталога, а именно Admin и User.
Далее мы создаем систему входа в систему с проверкой подлинности с помощью форм, которая поддерживает ролевую аутентификацию. Поскольку Microsoft не предоставляет простой механизм реализации, нам придется потратить некоторое время на создание билета аутентификации самостоятельно. Он должен хранить небольшой объем информации. Конечно, некоторые имена должны совпадать с теми, которые настроены в Web.config, иначе ASP.NET посчитает ваш билет аутентификации недействительным и заставит вас перенаправить на страницу входа. Мы добавляем два элемента управления TextBox в Login.aspx в VS.NET и называем их UserNameTextBox и PasswordTextBox. Мы также добавляем кнопку и называем ее LoginButton. Щелкните ее, чтобы ввести фоновый код. Добавьте необходимый код в метод LoginButton_Click. следующее:
программный код
частная пустота LoginButton_Click (отправитель объекта, System.EventArgs e)
{
//Инициализация проверки подлинности форм
// Обратите внимание, что он находится в пространстве имен System.Web.Security
// Итак, добавьте using System.Web.Security в начале кода;
FormsAuthentication.Initialize()
// Создание объектов подключения к базе данных и командных объектов работы с базой данных
// Обратите внимание, что он находится в пространстве имен System.Data.SqlClient
// Итак, добавьте использование System.Data.SqlClient в начале кода;
SqlConnection конн =
new SqlConnection("Источник данных=sun-willmove;интегрированная безопасность=SSPI;Начальный каталог=WebSolution;");
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "Выберите роли пользователей ИЗ пользователей, где имя пользователя=@имя пользователя " +
"И Пароль=@пароль ";
// Заполняем каждый параметр
cmd.Parameters.Add("@username", SqlDbType.NVarChar, 100).Value =
ИмяПользователяTextBox.Текст;
cmd.Parameters.Add("@password", SqlDbType.NVarChar, 150).Value =
FormsAuthentication.HashPasswordForStoringInConfigFile(
PasswordTextBox.Text, "md5"); // или "sha1"
// Выполнить команду операции с базой данных
конн.Открыть();
Читатель SqlDataReader = cmd.ExecuteReader();
если (читатель.Читать())
{
// Для реализации аутентификации создаем новый билет
Билет FormsAuthenticationTicket = новый FormsAuthenticationTicket(
1, // номер версии билета
UserNameTextBox.Text, // Владелец билета
DateTime.Now, //Время распределения билетов
DateTime.Now.AddMinutes(30), //Срок действия
правда, //требуется файл cookie пользователя
reader.GetString(0), // Данные пользователя, здесь собственно роль пользователя
FormsAuthentication.FormsCookiePath);//Действительный путь к файлу cookie
//Используйте машинный ключ машинного кода для шифрования файлов cookie для безопасной передачи
строковый хеш = FormsAuthentication.Encrypt(билет);
Файл cookie HttpCookie = новый HttpCookie(
FormsAuthentication.FormsCookieName, // Имя файла cookie аутентификации
hash); //Зашифрованный файл cookie
//Устанавливаем срок действия файла cookie в соответствии со сроком действия билетов.
if (ticket.IsPersistent) cookie.Expires = Ticket.Expiration
//Добавляем файлы cookie в ответ на запрос страницы
;
Response.Cookies.Add(cookie);
//Перенаправляем пользователя на ранее запрошенную страницу,
// Если ни одна страница ранее не запрашивалась, перенаправляем на домашнюю страницу
строка returnUrl = Request.QueryString["ReturnUrl"];
if (returnUrl == null) returnUrl = "./"
// Не вызывать метод FormsAuthentication.RedirectFromLoginPage.
// Потому что он заменит только что добавленный билет (cookie)
Response.Redirect(returnUrl);
}
еще
{
// Не сообщайте пользователю: «Пароль неправильный», это равносильно тому, чтобы дать злоумышленнику шанс.
// Потому что они знают, что введенное ими имя пользователя существует
//
ErrorLabel.Text = "Имя пользователя или пароль неверны. Повторите попытку!";
ErrorLabel.Visible = правда;
}
Reader.Close();
конн.Закрыть();
}
Код страницы aspx внешнего интерфейса выглядит следующим образом:
программный код
<%@ Page Language="c#" Codebehind="Login.aspx.cs" AutoEventWireup="false" Inherits="RolebasedAuth.Login" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<ГОЛОВКА>
<title>Войти</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content=" http://schemas.microsoft.com/intellisense/ie5 ">
</HEAD>
<тело>
<form id="Form1" метод="post" runat="server">
<П>
<asp:Label id="Label1" runat="server">Имя пользователя:</asp:Label>
<asp:TextBox id="UserNameTextBox" runat="server"></asp:TextBox></P>
<P><FONT face="宋体"> </FONT>
<asp:Label id="Label2" runat="server">Пароль:</asp:Label>
<asp:TextBox id="PasswordTextBox" runat="server" TextMode="Password"></asp:TextBox></P>
<П>
<asp:Label id="ErrorLabel" runat="server" Visible="False"></asp:Label></P>
<П>
<asp:Button id="LoginButton" runat="server" Text="Login"></asp:Button></P>
</форма>
</тело>
</HTML>
Вы заметите, что мы сделали с паролем выше: хешировали его. Хэш-шифрование — это односторонний алгоритм (необратимый), который генерирует уникальный массив символов. Таким образом, изменение регистра даже одной буквы в пароле приведет к созданию совершенно другого хэш-столбца. Мы храним эти зашифрованные пароли в базе данных, что более безопасно. В практическом применении вам может потребоваться восстановить забытый пароль пользователя. Но хеширование необратимо, поэтому восстановить исходный пароль не получится. Но вы можете изменить пароль пользователя и сообщить ему измененный пароль. Если сайт может выдать вам старые пароли, то вам нужно трезво подумать, ваши пользовательские данные не в безопасности! Фактически, большинство отечественных веб-сайтов хранят пароли пользователей напрямую в базе данных без шифрования. Если хакеру это удастся, эти учетные записи пользователей окажутся в опасности!
Без SSL ваш пароль передается по сети в виде открытого текста. Его могут украсть во время передачи. Шифрование паролей на стороне сервера обеспечивает лишь безопасность хранения паролей. Информацию, связанную с SSL, можно найти на http://www.versign.com или http://www.thewte.com .
Если вы не хотите хранить пароль в базе данных в зашифрованном виде, вы можете изменить приведенный выше код на
FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordTextBox.Text, «md5») можно изменить на PasswordTextBox.Text.
Далее нам нужно изменить файл Global.asax. Если в вашем веб-приложении нет этого файла, щелкните проект веб-приложения правой кнопкой мыши и выберите «Добавить->Добавить новый элемент...->Глобальный класс приложения». В Global.asax или Global.asax.cs найдите метод (функцию) с именем Application_AuthenticationRequest. Сначала убедитесь, что пространства имен System.Security.Principal и System.Web.Security включены или используются, а затем измените его. Измененный код:
программный код
protected void Application_AuthenticateRequest (отправитель объекта, EventArgs e)
{
если (HttpContext.Current.User! = ноль)
{
если (HttpContext.Current.User.Identity.IsAuthenticated)
{
если (HttpContext.Current.User.Identity — это FormsIdentity)
{
Идентификатор формы =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket Ticket = id.Ticket
// Получаем данные пользователя, хранящиеся в билете, что на самом деле здесь является ролью пользователя.
строка userData = Ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = новый GenericPrincipal (id, роли);
}
}
}
}
Билет аутентификации (имя пользователя и пароль) не сохраняется как часть файла cookie и не может быть сохранен, поскольку пользователи могут изменять свои файлы cookie.
Фактически, FormsAuthentication использует ваш машинный ключ (обычно в файле Machine.config) для шифрования билета (FormsAuthenticationTicket). Мы используем UserData для хранения ролей пользователей и создания новых учетных данных. После создания учетных данных они добавляются в текущий контекст (т. е. HttpContext), чтобы их можно было использовать для получения роли пользователя.
Затем мы настраиваем секретный каталог (то есть «каталог безопасности», каталог, доступ к которому имеют только определенные пользователи, например администраторы). Сначала проверьте, есть ли файл Web.config в корневом каталоге вашего веб-приложения. Если нет, создайте его. Вы также можете создать файл Web.config в своем подкаталоге. Конечно, использование этого файла Web.config ограничено (некоторые параметры нельзя установить).
Чтобы реализовать безопасную аутентификацию, найдитепрограммный код
в узле <system.web> файла Web.config в корневом каталоге веб-приложения.
<authentication mode="Windows" /> измените его на
<authentication mode="Forms">
<forms name="AMUHOUSE.ASPXAUTH"
loginUrl="Логин.aspx"
защита="Все"
путь="./" />
</аутентификация>
<авторизация>
<разрешить пользователей="*"/>
</authorization>
В названии name="AMUHOUSE.ASPXAUTH" выше имя AMUHOUSE.ASPXAUTH является произвольным. Для управления разрешениями пользователей или групп пользователей мы можем использовать два метода: один — настроить файл Web.config в корневом каталоге приложения, а другой — создать независимый файл Web.config в секретном каталоге. (Последнее может быть лучше.) В первом случае файл Web.config должен содержать следующее содержимое (или подобное содержимое):
программный код
<конфигурация>
<система.веб>
<режим аутентификации="Формы">
<forms name="AMUHOUSE.ASPXAUTH"
loginUrl="login.aspx"
защита="Все"
путь="/"/>
</аутентификация>
<авторизация>
<разрешить пользователей="*"/>
</авторизация>
</система.веб>
<путь к местоположению="./Администратор">
<система.веб>
<авторизация>
<!-- Внимание! Порядок и регистр следующих строк очень важны! -->
<allow roles="Администратор"/>
<запретить пользователей="*"/>
</авторизация>
</система.веб>
</местоположение>
<путь к местоположению="./Пользователь">
<система.веб>
<авторизация>
<!-- Внимание! Порядок и регистр следующих строк очень важны! -->
<allow roles="Пользователь"/>
<запретить пользователей="*"/>
</авторизация>
</система.веб>
</местоположение>
</конфигурация>
Чтобы каталоги веб-приложений раньше не зависели друг от друга и их было проще переименовывать или перемещать, вы можете настроить отдельный файл Web.config в каждом подкаталоге безопасности. Требуется только настроить узел <authorization/> следующим образом:
программный код
<конфигурация>
<система.веб>
<авторизация>
<!-- Внимание! Порядок и регистр следующих строк очень важны! -->
<allow roles="Администратор"/>
<запретить пользователей="*"/>
</авторизация>
</система.веб>
</конфигурация>
Следует еще раз напомнить, что приведенные выше роли чувствительны к регистру. Для удобства вы также можете изменить приведенное выше:
<allow roles="Администратор,администратор" />
Если вы хотите разрешить или запретить доступ нескольких ролей к этому каталогу, вы можете разделить их запятыми, например:
<allow roles="Администратор,Член,Пользователь" />
<denyusers="*" />
На этом этапе мы настроили механизм аутентификации на основе ролей для веб-сайта. Вы можете сначала скомпилировать свою программу, а затем попытаться получить доступ к секретному каталогу, например http://localhost/RolebasedAuth/Admin , после чего вы будете перенаправлены на страницу входа пользователя. Если вы успешно войдете в систему и ваша роль имеет права доступа к этому каталогу, вы вернетесь в этот каталог. Могут быть пользователи (или злоумышленники), пытающиеся войти в конфиденциальный каталог. Мы можем использовать сеанс для хранения количества раз, когда пользователь входил в систему. Если это число превышает определенное число, пользователю не будет разрешено войти в систему. и «Система отклонила ваш запрос на вход!».
Ниже мы обсудим, как заставить веб-элементы управления отображать различное содержимое в зависимости от ролей пользователя.
Иногда лучше отображать контент на основе роли пользователя, потому что вы, вероятно, не захотите создавать кучу страниц с большим количеством дублированного контента для такого количества разных ролей (групп пользователей). На таком сайте могут сосуществовать различные учетные записи пользователей, а платные учетные записи пользователей могут получать доступ к дополнительному платному контенту. Другим примером является страница, на которой будет отображаться кнопка «Войти в администратора», ссылающаяся на страницу администратора, если текущий пользователь находится в роли «Администратора». Мы сейчас реализуем эту страницу.
Класс GenericPrincipal, который мы использовали выше, реализует интерфейс IPincipal. Этот интерфейс имеет метод IsInRole(), а его параметром является строка. Эта строка представляет собой роль пользователя, которую необходимо проверить. Если мы хотим отображать контент вошедшим в систему пользователям с ролью «Администратор», мы можем добавить следующий код в Page_Load:
Программный код
если (User.IsInRole("Администратор"))
AdminLink.Visible = true;
Весь код страницы выглядит следующим образом (для простоты фоновый код также прописан на странице aspx):
программный код
<html>
<голова>
<title>Добро пожаловать! </title>
<script runat="сервер">
protected void Page_Load (отправитель объекта, EventArgs e)
{
если (User.IsInRole("Администратор"))
AdminLink.Visible = правда;
еще
AdminLink.Visible = ложь;
}
</скрипт>
</голова>
<тело>
<h2>Добро пожаловать! </h2>
<p>Добро пожаловать в Дом Аму http://amuhouse.com/ ^_^</p>
<asp:HyperLink id="AdminLink" runat="server"
Text="Главная страница администратора" NavigateUrl="./Admin"/>
</тело>
</html>
Таким образом, элемент управления HyperLink, связанный с каталогом администратора, будет отображаться только пользователям с ролью администратора. Вы также можете предоставить незарегистрированным пользователям ссылку на страницу входа, например:
программный код
protected void Page_Load (отправитель объекта, System.EventArgs e)
{
if (User.IsInRole("Администратор"))
{
AdminLink.Text = "Администратор, пожалуйста, войдите";
AdminLink.NavigateUrl="./Admin";
}
иначе, если(User.IsInRole("Пользователь"))
{
AdminLink.Text = "Зарегистрированные пользователи, пожалуйста, войдите";
AdminLink.NavigateUrl="./Пользователь"
}
;
еще
{
AdminLink.Text = "Пожалуйста, войдите в систему";
AdminLink.NavigateUrl="Login.aspx?ReturnUrl=" + Request.Path;
}
}
Здесь, установив переменную QueryString с именем ReturnUrl, мы можем вернуть пользователя на текущую страницу после успешного входа в систему.
краткое содержание:
Эта статья поможет вам понять важность и практичность механизмов безопасности на основе ролей, а также использует ASP.NET для реализации механизмов безопасности на основе ролей. Это несложный механизм для реализации, но он может потребовать некоторых знаний о том, что такое учетные данные пользователя, как аутентифицировать пользователей и как аутентифицировать авторизованных пользователей. Я был бы очень рад, если бы это было вам полезно. Я надеюсь, что он поможет вам реализовать аутентификацию безопасности на основе ролевых форм на вашем веб-сайте.
Прикрепил:
Пример исходного кода проекта для этой статьи: