Как обработать событие страницы перед перенаправлением проверки подлинности с помощью форм? - PullRequest
2 голосов
/ 08 марта 2010

У меня есть веб-сайт, который использует базовую аутентификацию форм ASP.Net. В файле web.config мы указываем конкретные правила доступа для отдельных страниц и каталогов. Все отлично работает.

Однако теперь у меня есть новые требования. Мой домен содержит множество разных сайтов, настроенных среди разных поддоменов. У меня есть два поддоменов DNS, которые сопоставляются с этим приложением. Одним из них является aaa.mysite.com, а другим - www.mysite.com. Если с субдомена aaa.mysite.com получен определенный веб-запрос для страницы, защищенной FormsAuthentication, до обработки логики FormsAuthentication (пользователь будет перенаправлен на страницу входа в систему), сначала я хочу выполнить некоторый код. Этот код, по сути, будет пытаться прочитать cookie из третьего субдомена, например, zzz.mysite.com, и, если он не существует, Response.Radirect для страницы входа в приложении zzz.mysite.com.

Я попытался обработать это через базовый класс, от которого могла бы унаследоваться любая из моих страниц, защищенных проверкой подлинности с помощью форм, и затем вызвал специальный код в функции Page_PreInit. Однако FormsAuthentication обрабатывает перенаправление на страницу входа в систему даже до вызова функции PreInit.

Кто-нибудь знает хороший способ справиться с этим делом? Если Page_PreInit не будет работать, где я могу поместить код так, чтобы он выполнялся до перенаправления FormsAuthentication, но где у меня также есть доступ к какой странице он находится (и от какого класса он наследуется, так что я могу видеть, наследуется ли он от System.Web.UI.Page или, если он унаследован от моего специального BasePage).

Есть идеи? Я думаю, что я мог бы использовать Globals Application_BeginRequest, но тогда это будет вызываться для каждого отдельного запроса, что не очень хорошая идея.

Я не могу быть первым человеком, которому нужен способ обработки события до FormsAuthentication, поэтому, пожалуйста, если вы могли бы дать мне некоторые дополнительные идеи, я был бы очень признателен!

Спасибо!

Ответы [ 2 ]

1 голос
/ 08 марта 2010

Если файл cookie был записан в zzz.example.com, то сайт на www.example.com не может его прочитать - способ поделиться файлами cookie между поддоменами - записать их в .example.com.

Это можно настроить в проверке подлинности с помощью атрибута domain в элементе форм в web.config:

<forms [...]
   domain=".example.com">

Обратите внимание на начальный период в доменных именах.

Изменить, чтобы ответить на комментарий

Вероятно, вам следует подключиться к событию PostAuthenticateRequest - оно запускается после установления личности пользователя (или его отсутствия), и вы можете зарегистрировать пользовательский HttpModule для получения событие.

Изменить, чтобы показать работу

Хорошо, я только что протестировал следующую настройку:

Проект веб-приложения со следующей структурой каталогов:

/Default.aspx                    -- Simple aspx page.
/Login.aspx                      -- Simple aspx page, with a Login control.
/web.config                      -- Main application config.
/Classes/CheckingAuthenticate.cs -- HttpModule, configured in root.
/Restricted/Default.aspx         -- Simple asp page.
/Restricted/web.config           -- Config file for authorization

Итак, корневой web.config устанавливает проверку подлинности с помощью форм с использованием стандартного поставщика членства ASP.NET и устанавливает /Login.aspx в качестве страницы входа. Я также зарегистрировал там собственный HttpModule:

<httpModules>
  <add name="CheckingAuthenticate" 
       type="TempWebApp.Classes.CheckingAuthenticate"/>
  [...]
</httpModules>

web.config в /Restricted/ запрещает доступ анонимным пользователям (это можно сделать и в элементе <location> в корне):

<configuration>
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</configuration>

У меня в http-модуле следующий код:

using System;
using System.Web;
using System.Web.Security;

namespace TempWebApp.Classes {
  public class CheckingAuthenticate : IHttpModule {

    public void Dispose() {
        //clean-up code here.
    }

    public void Init(HttpApplication context) {
      context.PostAuthenticateRequest += OnPostAuthenticate;
    }

    public void OnPostAuthenticate(object sender, EventArgs e) {
      var app = sender as HttpApplication;

      if (!UrlAuthorizationModule.CheckUrlAccessForPrincipal(app.Request.Path,
                                                            app.User,
                                                            "GET")){
        //Code here to read cookies, redirect user etc.
      }
    }
  }
}

Это сработает после аутентификации пользователя, но до того, как ASP.NET попытается авторизовать пользователя, так что вы получите возможность самостоятельно проверить доступ и вместо этого перенаправить. Я был в состоянии достигнуть точек останова на этом довольно счастливо. Я не смог увидеть события AuthorizeRequest или PostAuthorizeRequest, если у пользователя не было доступа к этим страницам.

1 голос
/ 08 марта 2010

Я думаю, что вы должны использовать событие AuthenticateRequest. См. жизненный цикл . Не беспокойтесь о том, что это происходит при каждом запросе, многие вещи делают это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...