По существу, это оптимальный вариант — знакомые интерфейсы и удобные службы приложений .NET Framework и ASP.NET 2.0, такие, как управление членством и ролями, плюс неограниченная возможность расширения сервера, ранее доступная только составляющим ISAPI, написанным на C.
В добавление к возможности написания новых модулей ASP.NET, основанной на особых преимуществах режима Integrated, многие унаследованные модули ASP.NET можно сделать гораздо более мощными простым изменением нескольких параметров настройки в файле web.config.
Рис 4. Жизненный цикл ASP.NET
Для разработчиков ASP.NET преимущества интегрированного конвейера заключаются в следующем:
Модули управляемого кода в службах IIS 7.0
Жизненный цикл приложения ASP.NET можно расширить с помощью модулей, в которых реализован интерфейс IHttpModule. Модули, в которых реализован интерфейс IHttpModule, являются модулями управляемого кода. Интегрированный конвейер ASP.NET и IIS 7.0 также можно расширить с помощью модулей машинного кода, которые в данном разделе не рассматриваются. Модуль управляемого кода можно задать как файл класса в папке App_Code приложения. Также можно создать модуль как проект библиотеки классов, скомпилировать его и добавить в папку Bin приложения. После создания настраиваемого модуля его необходимо зарегистрировать с помощью IIS 7.0. Для управления модулями управляемого кода IIS 7.0 можно воспользоваться одним из описанных ниже методов. Например, чтобы зарегистрировать модуль управляемого кода только для одного приложения, можно изменить файл Web.config этого приложения. Если модуль находится в папке App_Code или Bin и зарегистрирован в файле Web.config приложения, этот модуль вызывается только для этого приложения. Чтобы зарегистрировать модуль Web.config приложения, необходимо изменить элемент modules в разделе system.webServer. Изменения, внесенные с помощью IIS Manager или средства Appcmd.exe, вносятся в файл Web.config приложения.
Модули управляемого кода также можно зарегистрировать в элементе modules хранилища конфигурации IIS 7.0 (файл ApplicationHost.config). Модули, зарегистрированные в файле ApplicationHost.config, обладают глобальной областью действия, поскольку они зарегистрированы для всех веб-приложений, размещенных с помощью служб IIS 7.0. Модули машинного кода, заданные в элементе globalModules файла ApplicationHost.config, также обладают глобальной областью действия. Если глобальный модуль в веб-приложении не используется, его можно отключить.
Мною был реализован процесс аутентификации и проверки подлинности пользователей входящих на сайт. В него входят: страница, сценарий которой сверяет введенные пользователем данные с хранящимися в базе пользователей и формирует билет аутентификации, хранимый в cookies пользователя, и пользовательский модуль IIS, который проверяет наличие правильного билета и в последствие может быть расширен в соответствии с логикой приложения. Например, проверка роли пользователя и запрет на обращение к определенным страницам или сокрытие управляющих конструкций, при недостаточных правах.
При правильной настройке сервера действия, прописанные в модуле будут вызываться всякий раз при обращении пользователя к любому ресурсу сервера. Хоть система безопасности отклоняет «подозрительные» запросы к ресурсам, можно в написать свой модуль или обработчик, анализирующий и отклоняющий опасные запросы и попытки атак.
Модуль реализован с применением стандартного класса IHttpModule.
public class userAuth : IHttpModule
{
public void Init(HttpApplication app)
{
app.AuthenticateRequest += new EventHandler(this.Authorize);
}
При каждом обращении к странице возникает событие AuthenticateRequest, на которое модуль реагирует обработчиком события Authorize
public void Authorize(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
try
{
string page = context.Request.CurrentExecutionFilePath if ((!Regex.IsMatch(page, "Default.aspx", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(page, "ProductList.aspx", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(page, "SearchResult.aspx", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(page, "Register.aspx", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(page, "Login.aspx", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(page, "ErrorPage.aspx", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(page, "ProductDetails.aspx", RegexOptions.IgnoreCase)))
{
if (context.Request.IsAuthenticated)&&(!Regex.IsMatch(page, "Management.aspx", RegexOptions.IgnoreCase)))
{
return;
}
else
if ((context.Request.IsAuthenticated)&&(Regex.IsMatch(page, "Management.aspx", RegexOptions.IgnoreCase)))
{
if (context.Request.Cookies.Get("auth").Value != null)
{
FormsAuthenticationTicket tick = FormsAuthentication.Decrypt(context.Request.Cookies.Get("auth").Value); string s = tick.UserData.ToString();
if (!Regex.IsMatch(s, "admin", RegexOptions.IgnoreCase))
{
context.Application["error"] = "Not enough rights";
context.Response.Redirect("~/ErrorPage.aspx");
}
}
else
{
context.Application["error"] = "Not enough rights";
context.Response.Redirect("~/ErrorPage.aspx");
}
}
}
else
return;
}
catch (Exception ex)
{
}
}
Если у пользователя, запрашивающего старницу нет аутонтификационного cookies он переадресовывается на страницу авторизации Login.aspx, на которой главный метод контрола Login1 проверяет наличие пользователя в базе и создает аутентификационный билет, записываемый в cookies.
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
UserConnect accountSystem = new UserConnect();
string IDuser = accountSystem.UserLogin(Login1.UserName, Security.Encrypt(Login1.Password));
string userrole = accountSystem.UserRole(Login1.UserName);
if (IDuser != null)
{
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(IDuser, Login1.DisplayRememberMe);
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, userrole);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
authCookie.Name = "auth";
Response.Cookies.Add(authCookie);
Response.Redirect("Defalt.aspx");
}
else
Response.Write("Can't authentificate <br/>");
}
Класс UserConnect содержит методы для вытягивания из базы информации о пользователях и записи ее туда.
Используемый нами метод UserLogin
public string UserLogin(string email, string password)
{
//CustomerDetails
int Iduser;
using( SqlConnection myConnection = new SqlConnection(ConnectionString))
using (SqlCommand myCommand = new SqlCommand("[dbo].[UserLogin]", myConnection))
{
myCommand.CommandType = CommandType.StoredProcedure;
// Add Parameters to SPROC
SqlParameter parameterEmail = new SqlParameter("@email", SqlDbType.NVarChar, 20, "email");
parameterEmail.Value = email;
myCommand.Parameters.Add(parameterEmail);
SqlParameter parameterPassword = new SqlParameter("@password", SqlDbType.NVarChar, 20, "password");
parameterPassword.Value = password;
myCommand.Parameters.Add(parameterPassword);
SqlParameter RetVal = new SqlParameter("@IDuser", SqlDbType.Int, 30);
RetVal.Direction = ParameterDirection.Output;
myCommand.Parameters.Add(RetVal);
// Open the connection and execute the Command myConnection.Open();
myCommand.ExecuteNonQuery();
Iduser = Convert.ToInt32(RetVal.Value);
myConnection.Close();
}
if (Iduser == 0)
{
return null;
}
else
{
return Iduser.ToString();
}
}
В итоге при введение в строку поиска адреса страницы, на которую нельзя попасть, не пройдя авторизацию, запрос будет переадресова на страницу входа. (См. рис. 5,6)
Рис 5. Попытка неавторизованного входа
Рис 6. Результат попытки неавторизованного входа
Если пользователь входит в группу администраторы, то при входе ему будут видны и доступны страницы управления, а обычным пользователям нет.
Рис. 7 главное меню Администратора
Рис 8. Возможности администратора
Рис 9. Главная страница обычного пользователя
В своей работе я добился поставленных целей. Изучив работу ASP.NET и IIS 7.0 я научился создавать безопасные веб-приложения. Благодаря модульной архитектуре IIS 7.0 запросы буду проверяться самим сервером до передачи управления приложению. Разработанный мною механизм авторизации и проверки подлинности можно усовершенствовать, добавив проверку подлинности на основе ролей. Гибкость в настройке сервера позволяет переносить приложения простым копированием, поэтому написанное мною приложение легко распостранимо.
Подводя итоги, можно сказать, ASP.NET 2.0 и IIS 7.0 – мощный инструмент для разработки управления и поддержки веб-приложений, который можно и нужно использовать.
1. Троелсен Э. «C# и платформа .NET. Библиотека программиста» - СПб.: Питер 2007 796л.
2. Глинн, Джей, Ивьен, Билл, Нейгел, Кристиан, Скиннер, Морган, Уотсон, Карли. C# и платформа .NET 3.0 для профессионалов. : Издательский дом «Вильямс», 2008. – 1376+416 с.
3. Общие сведения о жизненном цикле приложения ASP.NET для служб IIS 7.0 статья с http://msdn.microsoft.com/ru-ru/library/bb470252.aspx 10.05.09
4. Архитектура безопасности ASP.NET http://msdn.microsoft.com/ru-ru/library/yedba920.aspx 6.05.09