У меня есть два веб-приложения .NET, работающие на одном сервере — sentinel (размещенном по адресу https://sentinel.mydomain.com/) и fortknox (по адресу http://www.mydomain.com/fortknox)
Sentinel — это «портал» аутентификации. FortKnox — это приложение для проверки концепции, в котором используется проверка подлинности с помощью форм, но для параметра loginUrl задано значение https://sentinel.mydomain.com/login (вместе со специальным обработчиком Application_EndRequest для уточнения ReturnUrl). Sentinel написан на .NET 4.0 с использованием MVC 4 и Razor; FortKnox — это ASP.NET MVC 2, использующий .NET 2.0.
Я использую ASP.NET FormsAuthentication с доменом cookie, установленным на .mydomain.com
, поэтому файлы cookie, установленные sentinel.mydomain.com
, будут отправляться с запросами на www.mydomain.com
и наоборот. Часть с файлами cookie работает отлично — оба приложения получают один и тот же билет зашифрованных форм .ASPXAUTH.
Проблема в том, что на наших рабочих серверах fortknox не может расшифровать файлы cookie, созданные sentinel, даже если они имеют идентичные машинные ключи. Даже когда оба приложения работают на одном физическом устройстве, оно не работает.
Пользователь нажимает на fortknox, он перенаправляется на sentinel, он входит в систему, устанавливается файл cookie, он перенаправляется обратно на fortknox, а затем я получаю «Невозможно проверить данные»:
Exception: Unable to validate data.
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo, Boolean signData)
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.Security.FormsAuthentication.Decrypt(String encryptedTicket)
at FortKnox.Web.MvcApplication.Application_BeginRequest()
Машинные ключи идентичны — я дошел до того, что включил этот кусок (неприятного!) кода в разметку каждой страницы:
try {
var cookie = Request.Cookies[".ASPXAUTH"].Value;
Response.Write("Cookie: " + cookie + Environment.NewLine);
var ticket = FormsAuthentication.Decrypt(cookie);
Response.Write("Ticket name: " + ticket.Name + Environment.NewLine);
} catch (Exception x) {
Response.Write("Exception: " + x.Message + Environment.NewLine);
Response.Write(x.StackTrace);
}
Response.Write("<hr /></pre>");
var machineConfigMachineKey = (MachineKeySection)WebConfigurationManager.OpenMachineConfiguration().SectionGroups["system.web"].Sections["machineKey"];
var webConfigMachineKey = (MachineKeySection)WebConfigurationManager.OpenWebConfiguration("").SectionGroups["system.web"].Sections["machineKey"];
Response.Write("<pre>");
Response.Write("<b>machine.config decrypt: </b>" + machineConfigMachineKey.DecryptionKey + "<br />");
Response.Write("<b>web.config decrypt: </b>" + webConfigMachineKey.DecryptionKey + "<br />");
Response.Write("<br />");
Response.Write("<b>machine.config validate: </b>" + machineConfigMachineKey.ValidationKey + "<br />");
Response.Write("<b>web.config validate: </b>" + webConfigMachineKey.ValidationKey + "<br />");
Response.Write("</pre>");
Response.Write("<hr />");
и проверил, что машинные ключи, используемые во время выполнения, точно такие же.
Что особенно расстраивает, так это то, что это работало на наших серверах разработки и промежуточных серверов, и только в производстве. Единственная разница между серверами заключается в том, что на производственных блоках часто устанавливаются обновления Windows, в то время как на наших dev/staging блоках могут отсутствовать некоторые обновления; в остальном они идентичны (клонированы из одного и того же образа и созданы с использованием одних и тех же сценариев установки)
Итак... тот же сервер; такой же машинный ключ. ASP.NET 4 устанавливает файл cookie FormsAuthentication. Приложение ASP.NET 2 не может его расшифровать. Ошибка возникает только на определенных серверах; на других работает. На данный момент я полностью застрял... есть идеи?
РЕДАКТИРОВАНИЕ: Живой сервер обновлен до последнего уровня исправления. я пытался применить
<add key="aspnet:UseLegacyEncryption" value="true" />
как true И false, как для приложения входа в систему, так и для приложения fortknox. Все равно не повезло...