Защита cookie-файлов для проверки подлинности с помощью форм при разгрузке SSL
Я пытаюсь защитить веб-сайт, который я в настоящее время разрабатываю, используя ASP.NET MVC 2.0 и аутентификацию на основе форм. Чтобы защитить cookie-файл для проверки подлинности с помощью форм, я хочу установить для свойства requireSSL значение true, чтобы cookie-файлы отправлялись браузерами только при подключении по SSL, и, очевидно, гарантировали, что все ресурсы, для которых требуется авторизация, работают по SSL.
Моя проблема заключается в том, что мы используем маршрутизацию запросов приложений для выполнения ряда функций, одной из которых является разгрузка SSL, поэтому к тому моменту, когда запрос попадает на любой веб-сервер в нашей ферме, запрос больше не находится под SSL, а метод FormsAuthentication.SetAuthCookie завершается сбоем, поскольку SSL-соединение требуется для установки файла cookie, когда указано значение SSSSL.
У любого есть какие-нибудь идеи относительно работы здесь!
Спасибо
2 ответа
Так что у меня есть обходной путь для этого, однако, если у кого-то есть идеи получше, пожалуйста, не стесняйтесь комментировать. По сути, вам нужно перехватить ответ в конце запроса и вручную установить свойство Secure в файле cookie проверки подлинности форм, что довольно очевидно, вам также нужно будет установить для свойства requireSSL в конфигурации проверки подлинности формы значение false. Также имейте в виду, что мы не хотим включать HTTPS для всего сайта для аутентифицированных пользователей, поэтому это обходной путь.
Есть несколько предостережений к этому подходу и несколько вещей, о которых нужно знать.
Во время тестирования я обнаружил, что куки-файл аутентификации форм всегда записывался в ответ, поэтому я продолжал перезаписывать действительный куки-файл аутентификации в браузере пустым куки-файлом аутентификации, чтобы обойти это, я включил некоторую логику в модуль HTTP, чтобы обойти эту проблему. см. фрагмент кода ниже.
Все запросы к приложению, требующие авторизации, должны выполняться по протоколу SSL, в противном случае запрос не будет содержать файл cookie для аутентификации для аутентификации пользователя.
Поскольку вы передаете cookie-файл аутентификации только для запросов SSL, вам понадобится другой механизм, чтобы сообщить вашему приложению, что текущий пользователь проходит проверку подлинности при просмотре не-SSL-областей сайта, я реализовал это с помощью дополнительного cookie-файла, который устанавливается, когда пользователь входит в систему и не имеет установленной даты истечения срока действия, поэтому истекает в конце сеанса пользователя, конечно, этот файл cookie удаляется, если пользователь выходит из системы.
Ниже приведена логика, реализованная в модуле HTTP, чтобы повлиять на вышесказанное, я тестировал это последние пару часов и пока не сталкивался с какими-либо проблемами, я обязательно обновлю этот пост, если я это сделаю!
Мы должны когда-либо отправлять куки аутентификации клиенту, только если пользователь только что вошел в систему, вот логика
- Если в запросе есть cookie-файл авторизации, пользователь уже прошел аутентификацию и использует SSL, поэтому убедитесь, что мы не отправляем новый cookie-запрос аутентификации в ответе.
- Если в запросе отсутствует cookie-файл авторизации, но в ответе есть допустимый файл cookie аутентификации, установите для него файл cookie аутентификации ответа, чтобы он передавался только браузером по протоколу SSL.
- Если в запросе отсутствует файл cookie авторизации, а в ответе указан недействительный или пустой файл cookie аутентификации, убедитесь, что мы удалили файл cookie ответа, чтобы не перезаписывать действительный файл cookie в браузере клиента.
private void EndRequest(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
if (ValidRequest(application.Request) && application.Response.Cookies.Count > 0)
{
//only do the below if the user is not logging out the site, if the user is logging out we can
//leave the default forms authentication behaviour which is to expire the auth cookie
if (application.Request.AppRelativeCurrentExecutionFilePath != "~/authentication/logoff")
{
var requestAuthCookie = application.Request.Cookies[FormsAuthentication.FormsCookieName];
var responseAuthCookie = application.Response.Cookies[FormsAuthentication.FormsCookieName];
if (requestAuthCookie != null && responseAuthCookie != null && responseAuthCookie.Value.IsNullOrEmpty())
{
application.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
}
else if (responseAuthCookie != null && !responseAuthCookie.Value.IsNullOrEmpty())
{
responseAuthCookie.Secure = true;
application.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
application.Response.Cookies.Add(responseAuthCookie);
}
else if (responseAuthCookie == null || responseAuthCookie.Value.IsNullOrEmpty())
{
application.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
}
}
}
}
Разгрузка SSL должна позволять вам устанавливать соединение SSL от оффлоадера SSL к веб-серверу.
Соединение SSL от SSL Offloader к веб-серверу должно использовать самое легкое и быстрое (и, возможно, самое слабое) шифрование.
Это позволяет вам использовать безопасные куки-файлы, снизить нагрузку на шифрование на серверах и избежать модификации вашего кода.