Сбой единого входа в ASP.NET 4.0 между родительским веб-сайтом и дочерним веб-приложением

У меня такая структура

www.website.com -> Веб-сайт ASP.NET 4.0

www.website.com/blog -> NET 4.0, веб-приложение

Оба выполняют проверку подлинности с помощью формы для одной и той же базы данных SQL и используют членство и роли платформы ASP.NET. Я могу нормально войти в каждую часть (тот же пользователь / пароль), но аутентификация не переносится, т.е. если я вхожу в /, а затем нажимаю ссылку на /blog/, /blog/ думает, что я анонимный, и снова запрашивает вход. Я сделал основы

i.e.

  1. Идентичный <authentication mode="Forms"> как на сайте, так и в приложении web.configs
  2. Идентичный <machineKey> раздел (да, одинаковые validationKey и decryptionKey)

Затем я проверил сгенерированные файлы cookie и заметил, что веб-сайт и веб-приложение, похоже, работают с разными файлами cookie.

Файлы cookie, созданные сайтом website.com/blog

  • .ASPXFORMSAUTH-27604f05-86ad-47ef-9e05-950bb762570c
  • .ASPXROLES

Файлы cookie, созданные сайтом website.com

  • .ASPXFORMSAUTH

Я думаю, что это проблема, хотя я вижу это, несмотря на то, что у меня есть одинаковые <authentication> разделы, которые выглядят как

<authentication mode="Forms">
    <forms timeout="30" slidingExpiration="true" name=".ASPXFORMSAUTH" enableCrossAppRedirects="true" protection="All" cookieless="UseCookies"/>
</authentication>

Я прочитал несколько других сообщений, таких как Single Sign On with Forms Authentication, а также http://msdn.microsoft.com/en-us/library/eb0zx8fc.aspx

Было также несколько других сообщений, которые я сейчас не могу вспомнить. Я прошел через них (все?), Но все еще застрял. При необходимости я с радостью предоставлю дополнительные данные для отладки.

Был бы очень признателен за любые советы, которые могут быть у кого-то! Я думаю, что упираюсь в стену на этом!


person DeepSpace101    schedule 08.10.2011    source источник


Ответы (2)


Хорошо, так что я смог ответить на свой вопрос после долгих размышлений.

По сути, BlogEngine.NET 2.5 (мое веб-приложение), похоже, переопределяет способ работы .NET 4.0. Есть несколько вещей, которые вам нужно исправить, все в BlogEngine.Core \ Security \ Security.cs (загрузите исходный код BlogEngine.NET)

Часть 1. Исправьте имя файла cookie

В нем есть метод FormsAuthCookieName, который я изменил следующим образом:

File: BlogEngine.Core\Security\Security.cs
Method: FormsAuthCookieName()
// return FormsAuthentication.FormsCookieName + "-" + Blog.CurrentInstance.Id.ToString();
return FormsAuthentication.FormsCookieName;

Это гарантирует, что имена файлов cookie совпадают. Одно препятствие вниз ...

Часть 2. Избегайте веб-приложения / страницы входа / элементов управления / кода BlogEngine.NET

Вместо того, чтобы направлять пользователей для входа на страницу login.aspx BlogEngine.Net (www.website.com \ blog \ account \ login.aspx), я указал все ссылки для входа на страницу login.aspx моего основного веб-сайта ( www.website.com \ login.aspx). Если вам интересно, как реализовать свою собственную аутентификацию на уровне сайта, это очень быстрое руководство.

msdn.microsoft.com/en-us/library/ff184050.aspx. 

Мне также пришлось добавить что-то подобное как на веб-сайт web.config, так и в веб-приложение web.config, поэтому при каждом доступе к защищенному ресурсу (с веб-сайта или веб-приложения) используется мой собственный global / login / aspx.

<authentication mode="Forms">
<forms timeout="30" loginUrl="/login.aspx" blah blah />
</authentication>

Теперь мои собственные общие для всего сайта элементы управления входом в систему будут создавать файлы cookie аутентификации (стандарт .NET framework) и файлы cookie ролей (пользователя). Избегая login.aspx BlogEngine.NET, мы чище, плюс мы избегаем вызова этого кода, который является проблематичным.

File: BlogEngine.Core\Security\Security.cs
Method: AuthenticateUser(string username, string password, bool rememberMe)

Подробности: Этот код добавляет "экземпляр блога" в файл cookie, поэтому, если у вас есть несколько блогов в одном домене, это предотвращает автоматическую аутентификацию пользователя user1 в экземпляре блога 1 на экземпляр блога 2. Я предполагаю, что у большинства будет только один блог на домен (www.domain.com \ blog!), так что в этом нет необходимости. Что еще более важно, эта проверка нарушает нашу систему единого входа.

Два препятствия вниз ...

Часть 3. Исправление проверки авторизации при каждом доступе

Теперь стандартизированный файл login.aspx для всего нашего сайта не добавляет конкретный идентификатор экземпляра BlogEngine.NET (см. Выше). Это было бы нормально, если бы не код BlogEngine.NET, который специально это ищет. Эта проверка нам тоже не нужна, так что давайте удалим эту проверку ...

File: BlogEngine.Core\Security\Security.cs
Method: void Init(HttpApplication context)
// Comment line below to revert to only-framework/default processing
//context.AuthenticateRequest += ContextAuthenticateRequest;

Итак, на этом этапе у вас должно быть

  • Все логины обрабатываются одним логином для всего сайта .aspx
  • Все файлы cookie аутентификации и файлы cookie ролей пользователя, созданные вышеупомянутым сайтом login.aspx
  • Все такие файлы cookie зашифрованы и защищены в соответствии с конфигурацией веб-сайта и веб-приложения web.configs (которые должны совпадать!)

Что, в свою очередь, позволяет использовать единый вход :) !! Ура!

person DeepSpace101    schedule 11.10.2011
comment
Я бы посоветовал посмотреть, не можете ли вы сделать свои изменения настраиваемыми и принять их сопровождающими. Мне кажется, что это в основном компромисс между несколькими движками в одном домене и единым входом - возможно, вам придется выбрать один или другой, но пользователям не нужно отлаживать, чтобы он работал ... - person jmoreno; 11.10.2011

Вдобавок: в оба файла web.configs вы должны вставить машинный ключ с одним и тем же ключом проверки и одним и тем же ключом дешифрования.

person Alek    schedule 06.01.2013