.net URL переписывание для локализации, проблемы с проверкой подлинности форм и loginUrl - PullRequest
1 голос
/ 31 июля 2009

Я использую HttpModule для перезаписи URL на многоязычном сайте. В модуле HttpModule я добавляю обработчик для события BeginRequest и ищу первую часть пути, содержащую имя культуры.

Например, /fr-ca/index.aspx будет переписан в /index.aspx, а культура потока и пользовательский интерфейс установлены на 3084. Это отлично работает.

Введите аутентификацию форм. Проверка подлинности с помощью форм по-прежнему работает с не отображенным URL-адресом, но если пользователь не авторизован, он будет перенаправлен на loginUrl, как установлено в разделе проверки подлинности web.config, и включит параметр? ReturnUrl = querystring для обработки перенаправления обратно на запрошенный страница, как только пользователь аутентифицирован.

Здесь есть две проблемы, если пользователь запрашивает страницу на языке, отличном от языка по умолчанию:

  1. loginUrl игнорирует путь перед его перезаписью
  2. Параметр ReturnUrl также игнорировал необработанный путь.

Это эквивалентно Request.Url.PathAndQuery вместо Request.RawUrl.

Я не могу перейти к конвейеру при событии AuthorizeRequest, потому что тогда мне придется защищаться от всех возможных значений культуры, потому что я использую один файл web.config с несколькими путями расположения. Это также не устраняет первую проблему.

Я прошел через FormsAuthenticationModule в отражателе, и я вижу, где я мог бы изменить его, чтобы решить # 1 и # 2, но он, конечно, запечатан.

Я также много осматривал, но не вижу работоспособных решений.

FormsAuthenticationModule проверяет заголовок 401, созданный в UrlAuthorizationModule. Если вы ищете реферера (который пуст) на странице loginUrl, это подтверждает это.

Есть мысли?

РЕДАКТИРОВАТЬ # 1

Я использую IIS 6, а IIS 7 не вариант.

РЕДАКТИРОВАТЬ # 2

Страница входа не собирала стандартную культуру / язык пользовательского интерфейса, поскольку при создании локального ресурса (представление «Дизайн»: «Инструменты»> «Создать локальный ресурс») среда IDE добавила в директиву страницы следующее:

culture = "auto" meta: resourcekey = "PageResource1" uiculture = "auto"

Будьте осторожны с этим в vs.net 2008! По крайней мере, это решает одну из проблем с культурой по умолчанию, на которую нет ссылок, но # 1 и # 2 все еще остаются нерешенными.

РЕДАКТИРОВАТЬ 3

Я надеялся, что смогу перейти в одно из событий конвейера, чтобы выполнить свое собственное перенаправление, но в методе Отражение System.Web.Security.UrlAuthorizationModule OnEnter я узнал, что после установки заголовка 401 метод вызывает приложение. CompleteRequest, который, как вы можете догадаться, приводит нас прямо к событию EndRequest. Это то, что модуль FA прыгает в do redirect, и я боюсь, что не могу прыгнуть вперед, чтобы сделать свой собственный редирект! Я удивлен, что больше людей не сталкивалось с этой проблемой, или, возможно, они еще не вмешались.


* * Пример тысяча сорок-девять:

У меня есть раздел участника в физической папке / members /, который защищен проверкой подлинности с помощью форм.

В web.config у меня есть:

<authentication mode="Forms">
  <forms loginUrl="~/members/login.aspx" timeout="40" />
</authentication>

и ...

  <location path="members">
      <system.web>
          <authorization>
              <deny users="?" />
              <allow roles="Members" />
              <deny users="*" />
          </authorization>
      </system.web>
  </location>

Когда неаутентифицированный пользователь запрашивает страницу индекса / members /, он перенаправляется на loginUrl из раздела аутентификации, описанного выше, с помощью FormsAuthenticationModule. Он также добавляет параметр? ReturnUrl к запрошенной странице.

Это прекрасно работает, если пользователь просматривает веб-сайт с использованием культуры по умолчанию, но мой HttpModule устанавливает культуру на основе наличия имени культуры в первой части пути.

Итак, /fr-ca/members/index.aspx переписывается в /members/index.aspx и устанавливает культурную / пользовательскую культуру для канадского французского. К сожалению, FormsAuthenticationModule отправляет пользователя на страницу loginUrl с переписанным URL, а не с оригиналом. Таким образом, настройка культуры потеряна, а URL перенаправления неверен.

Надеюсь, это поможет @ Грег

Ответы [ 2 ]

3 голосов
/ 01 августа 2009

Хорошо, проблема решена.

Оказалось, что ключ очищал http.Modules machine.config, добавлял мой собственный httpModule, затем добавлял обратно необходимые httpModules по умолчанию. Это позволило моему настраиваемому модулю httpModule перейти в событие EndRequest перед FormsAuthenticationHttpModule.

<httpModules>
    <clear/>
    <!-- custom -->
    <add name="LocalizationHttpModule" type="LocalizationHttpModule"/>
    <!-- add back defaults, exlude PassportAuthentication, AnonymousIdentification, Profile -->
    <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
    <add name="Session" type="System.Web.SessionState.SessionStateModule" />
    <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
    <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
    <add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
    <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
    <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />

</httpModules> 

Затем в моем пользовательском модуле httpModule я просто подключаюсь к EndRequest, ищу код состояния 401 и перенаправляю по своему желанию. По сути, я переписываю код из метода FormsAuthenticationHttpModule OnLeave для своих нужд.

Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init

    Dim authentication As AuthenticationSection = WebConfigurationManager.GetSection("system.web/authentication")
    If authentication.Mode = AuthenticationMode.Forms Then
        Me._LoginUrl = authentication.Forms.LoginUrl
        AddHandler context.EndRequest, AddressOf Context_EndRequest
    End If

End Sub

Private Sub Context_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
    Dim application As HttpApplication = DirectCast(sender, HttpApplication)
    Dim context As HttpContext = application.Context

    If (context.Response.StatusCode = &H191) Then                
       ' do custom redirect here
    End If

End Sub
1 голос
/ 31 июля 2009

О единственной вещи, которую я могу придумать, это сделать перенаправление на форму входа в систему вручную.

1) Разрешить всем доступ к каталогу членов
2) Все страницы в членстве напрямую наследуются от подкласса Page.
3) В PreInit (?) Подкласса Page проверьте, является ли пользователь членом членской роли.
4) Если нет, создайте URL-адрес страницы входа самостоятельно, включая параметр ReturnURL, и перенаправьте пользователя на свой адрес входа.

Вы также можете взломать это, поместив несколько разделов в ваш web.config. Пример: ... но я действительно не знаю.

Возможно, есть другие способы сделать это, с которыми я не знаком.

...