EPiServer и Windows Identity Foundation (WIF) - PullRequest
1 голос
/ 01 ноября 2011

Я изучаю возможности использования WIF для идентификации пользователей на частях сайта клиента, работающего на EPiServer.Мне удалось заставить WIF использовать следующий пост:

http://world.episerver.com/Blogs/Ben-Morris/Dates/2010/6/Converting-EPiServer-6-to-use-claims-based-authentication-with-WIF/

Это хорошо работает, если вы установите

<authorization>
    <deny users="?"/>
</authorization>

вweb.config, для выполнения всех запросов требуется аутентифицированный пользователь.Однако мы хотели бы использовать EPiServer для разделения того, какой контент должен быть доступен анонимным пользователям и аутентифицированным пользователям.Проблема в том, что я просто не могу заставить его работать.

Когда я включаю WIF и не устанавливаю deny users="*", EPiServer запускает и выводит некоторый текст в поток ответов, прежде чем WIF включитвыполнить перенаправление:

<code>HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Tue, 01 Nov 2011 07:51:04 GMT
Connection: close

Access denied.


Это приводит к следующей ошибке, когда WIF пытается перенаправить на STS:

Ошибка сервера в приложении '/'.

Невозможно перенаправить после отправки заголовков HTTP.

Описание: во время выполнения текущего веб-запроса произошло необработанное исключение.Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.Web.HttpException: невозможно перенаправить после отправки заголовков HTTP.

Ошибка источника:

Во время выполнения текущего возникло необработанное исключениевеб-запрос.Информацию о происхождении и местонахождении исключения можно определить с помощью следующей трассировки стека исключений.

Трассировка стека:

[HttpException (0x80004005): невозможно перенаправить после отправки заголовков HTTP.]System.Web.HttpResponse.Redirect (строковый URL-адрес, логический конечный ответ) + 8712587
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.RedirectToIdentityProvider (строковый uniqueId, строковый * returnUrl, пользовательский интерфейс WBWW).OnEndRequest (Отправитель объекта, аргументы EventArgs) + 438
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () +68 System.Web.HttpApplication.Execute *tep (IExyntionSonep)1067 *

Я искал как высокий, так и низкий, чтобы иметь возможность переопределить это поведение.В EPiServer.dll я нашел следующее место, где выводится текст, похожий на выводимый:

AccessDeniedDelegateHandler.cs, метод BrowserLogonAccessDenied(object sender):

internal static void BrowserLogonAccessDenied(object sender)
{
  HttpContext.Current.Response.Clear();
  HttpContext.Current.Response.Status = "401 Unauthorized";
  HttpContext.Current.Response.Write("Access denied.");
  HttpContext.Current.Response.Flush();
  HttpContext.Current.Response.End();
}

Этот код вызывается из следующегонасколько я вижу, в двух местах:

  • EPiServer.Global, метод protected virtual void HandleAccessDenied()
  • EPiServer.PageBase, метод public virtual void AccessDenied()

Я попытался переопределить HandleAccessDenied в Global.asax и переопределить AccessDenied в своем шаблоне страницы.Однако текст «Доступ запрещен» все еще выводится.Похоже, что переопределение AcccessDenied в моем шаблоне страницы срабатывает, однако переопределение HandleAccessDenied, похоже, не срабатывает.

Есть какие-нибудь подсказки, что здесь может быть не так?

Ответы [ 2 ]

1 голос
/ 02 ноября 2011

Нашел проблему. Я попытался переопределить AccessDenied метод PageBase, однако я сделал ту же «ошибку», что и реализация по умолчанию, а именно, чтобы очистить поток ответа:

    public override void AccessDenied()
    {
        Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        Response.Flush(); // <- This was the problem
        Response.End();
        // The rest is handled by WIF when we send a HTTP 401, think nothing more of it..
    }

Решение состояло в том, чтобы просто избежать очистки потока ответов. Тогда WIF обрабатывает остальное:

    public override void AccessDenied()
    {
        Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        // Removed the flushing of the response
        Response.End();
        // The rest is handled by WIF when we send a HTTP 401, think nothing more of it..
    }

Это позволяет нам использовать авторизацию EPI для контроля того, какие пользователи имели доступ к каждой странице.

0 голосов
/ 10 ноября 2011

Вместо переопределения поведения AccessDenied, вы можете добавить специальную форму входа (так как вы все еще полагаетесь на аутентификацию форм) для фактического запуска входа.

public class FederatedLoginHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.User.Identity.IsAuthenticated)
        {
            FormsAuthentication.RedirectFromLoginPage(context.User.Identity.Name, false);
        }
        else
        {
            context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
        }
    }
}

Установите обработчик в web.config с помощью

<system.webServer>
  <handlers>
    <!--"Fake" login handler, simply triggers WIF auth-->
    <add name="LoginForm" path="federatedlogin.ashx" verb="GET,HEAD" type="SomeAssembly.FederatedLoginHandler" />
    ...

И, наконец, настройте аутентификацию для использования нового обработчика

<authentication mode="Forms">
  <forms name=".LoginPage" loginUrl="federatedlogin.ashx" timeout="120" />
</authentication>

Эта стратегия не требует изменения EPiServer, WIF или стандартного поведения ASP.Net. Конечно, вам нужна базовая конфигурация WIF, чтобы заставить это работать http://msdn.microsoft.com/en-us/library/gg638734.aspx.

...