Невозможно проверить данные с помощью FormsAuthentication между различными веб-приложениями.

У меня есть два веб-приложения .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. Все равно не повезло...


person Dylan Beattie    schedule 05.07.2012    source источник
comment
У меня та же проблема, и я уже безуспешно пробовал 3 ключа, раньше он работал между 2.0 и 1.1, а в настоящее время работает с 2.0 и 1.1, но не может поделиться им с 4.0.   -  person    schedule 07.11.2013


Ответы (2)


Есть вероятность, что это как-то связано со старым патчем безопасности 2010 padding oracle - http://weblogs.asp.net/scottgu/archive/2010/09/28/asp-net-security-update-now-available.aspx? Попробуйте установить

<add key="aspnet:UseLegacyEncryption" value="true" />

заставить пропатченные серверы вести себя так, как они работали до патча?

(или, вы знаете... пропатчить ваши серверы. На ваш выбор.)

person James Hart    schedule 06.07.2012
comment
Чувак, если бы это были мои серверы, их бы уже пропатчили :) - person Dylan Beattie; 06.07.2012

Вы пробовали все следующие ключи? http://support.microsoft.com/kb/2425938

<add key="aspnet:UseLegacyEncryption" value="true" />
<add key="aspnet:UseLegacyMachineKeyEncryption" value="true" />
<add key="aspnet:ScriptResourceAllowNonJsFiles" value="true" />
person RealDealNeil    schedule 25.06.2013