Веб-приложение .Net за обратным прокси-сервером WebSeal

В настоящее время мы разрабатываем решение, которое будет работать как веб-приложение .Net за обратным прокси-сервером WebSeal.

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

Вопрос: кто-нибудь внедрил эту комбинацию технологий и заставил ее работать?


person Shiraz Bhaiji    schedule 21.09.2010    source источник
comment
Сталкивались ли вы с другими препятствиями?   -  person epotter    schedule 22.12.2010


Ответы (2)


Сначала у меня возникли некоторые проблемы с приложением ASP.Net при доступе через WebSeal. Я запускал сайт на сервере разработки. Что сработало для меня, так это развернуть приложение с отключенной отладкой в ​​​​файле конфигурации.

<compilation debug="false" ...>

При включенной отладке некоторые вызовы AJAX работали нормально при прямом доступе к сайту, но не работали при доступе через WebSeal. Как только я отключил отладку, все работает нормально.

Кроме того, поскольку WebSeal требует анонимной аутентификации, мы не могли использовать аутентификацию Windows.

person epotter    schedule 21.12.2010

Я сделал приложение ASP.NET, работающее за WEBSEAL. После долгих исследований, разработок и испытаний все работает.

Я предлагаю несколько вопросов, чтобы помочь вам:

IIS и ASP.NET нечувствительны к регистру.

("...Login.aspx" и "...login.aspx" ведут на одну и ту же страницу); по умолчанию webseal чувствителен к регистру. Поэтому вам следует настроить соединение WEBSEAL нечувствительным к регистру или проверить любую отдельную ссылку (страницу, javascript, изображение).

Внутренние ссылки, записанные как относительные URL-адреса сервера, не будут обслуживаться.

WEBSEAL изменяет любую ссылку, ссылающуюся на ваше приложение, но не изменяет ссылки на другие приложения. Внутренние ссылки, записанные как относительные URL-адреса сервера вместо относительные URL-адреса приложения, не будут изменены (WEBSEAL не распознает это то же самое приложение) и не будут обслуживаться ( WEBSEAL отклоняет неизмененные ссылки).
Первое правило – проверить любую отдельную ссылку и сделать ее относительным URL-адресом приложения.
Если вы обнаружите <.. href=/ anything>, посмотрите на отрендеренный HTML-код: это сервер. относительный URL, и это плохо.
Посмотрите в программном коде, если вы используете "= ~/ anything", это хорошо. Если вы используете "= / anything" ИЛИ ResolveUrl(..), это плохо.

Но этого недостаточно: AJAX помещает множество javascript и кода в ScriptResource.axd и WebResource.axd и создает относительный URL-адрес сервера, чтобы связать его. Эти ссылки не контролируются программистами, и нет простого способа их изменить.
Простое решение (если возможно): решите проблему сделав соединение WEBSEAL прозрачным .
Сложное решение: напишите следующий код (спасибо этот ответ)

protected void Page_Load(object sender, EventArgs e)
    {
        //Initialises my dirty hack to remove the leading slash from all web reference files.
        Response.Filter = new WebResourceResponseFilter(Response.Filter);
    }

public class WebResourceResponseFilter : Stream
{
    private Stream baseStream;

    public WebResourceResponseFilter(Stream responseStream)
    {
        if (responseStream == null)
            throw new ArgumentNullException("ResponseStream");
        baseStream = responseStream;
    }

    public override bool CanRead
    { get { return baseStream.CanRead; } }

    public override bool CanSeek
    { get { return baseStream.CanSeek; } }

    public override bool CanWrite
    { get { return baseStream.CanWrite; } }

    public override void Flush()
    { baseStream.Flush(); }

    public override long Length
    { get { return baseStream.Length; } }

    public override long Position
    {
        get { return baseStream.Position; }
        set { baseStream.Position = value; }
    }

    public override int Read(byte[] buffer, int offset, int count)
    { return baseStream.Read(buffer, offset, count); }

    public override long Seek(long offset, System.IO.SeekOrigin origin)
    { return baseStream.Seek(offset, origin); }

    public override void SetLength(long value)
    { baseStream.SetLength(value); }

    public override void Write(byte[] buffer, int offset, int count)
    {
        //Get text from response stream.
        string originalText = System.Text.Encoding.UTF8.GetString(buffer, offset, count);

        //Alter the text.
        originalText = originalText.Replace(HttpContext.Current.Request.ApplicationPath + "/WebResource.axd",
            VirtualPathUtility.MakeRelative(HttpContext.Current.Request.Url.AbsolutePath, "~/WebResource.axd"));
        originalText = originalText.Replace(HttpContext.Current.Request.ApplicationPath + "/ScriptResource.axd",
            VirtualPathUtility.MakeRelative(HttpContext.Current.Request.Url.AbsolutePath, "~/ScriptResource.axd"));

        //Write the altered text to the response stream.
        buffer = System.Text.Encoding.UTF8.GetBytes(originalText);
        this.baseStream.Write(buffer, 0, buffer.Length);

    }

Это перехватывает поток на страницу и заменяет все вхождения "/WebResource.axd" или "ScriptResource.axd" на "../../WebResource.axd" и "../../ScriptResource.axd"

Разработайте код, чтобы получить фактического пользователя WEBSEAL

WEBSEAL настроен на размещение имени пользователя внутри HTTP_IV_USER. Я создал форму Webseal\Login.aspx, чтобы читать ее программно. Теперь, чтобы сделать этого пользователя CurrentUser, я поместил скрытый asp.Login

<span style="visibility:hidden"> 
<asp:Login ID="Login1" runat="server" DestinationPageUrl="~/Default.aspx">..

и нажал кнопку программно

protected void Page_Load(object sender, EventArgs e)
{
    string username = Request.ServerVariables["HTTP_IV_USER"];
    (Login1.FindControl("Password") as TextBox).Text = MyCustomProvider.PswJump;
    if (!string.IsNullOrEmpty(username))
    {
        (Login1.FindControl("UserName") as TextBox).Text = username;
        Button btn = Login1.FindControl("LoginButton") as Button;
        ((IPostBackEventHandler)btn).RaisePostBackEvent(null);
     }
    else
    {
        lblError.Text = "Login error.";
    }
}

Когда срабатывает LoginButton, приложение считывает имя пользователя (устанавливается из переменной WEBSEAL) и пароль (жестко запрограммированный). Итак, я реализовал настраиваемого поставщика членства который проверяет пользователей и устанавливает текущий Принципал.

Изменения в web.config

loginUrl — URL-адрес для страницу входа, на которую будет перенаправлен класс FormsAuthentication. Он был установлен на портал WEBSEAL: неаутентифицированный пользователь и кнопка выхода будут перенаправлять на портал.

<authentication mode="Forms">
  <forms loginUrl="https://my.webseal.portal/" defaultUrl="default.aspx"...."/>
</authentication>

Поскольку Webseal/login.aspx НЕ является страницей входа по умолчанию, authorization предоставляет доступ неаутентифицированным пользователям:

<location path="Webseal/login.aspx">
    <system.web>
        <authorization>
            <allow users="*"/>
        </authorization>
    </system.web>
</location>

Приложение настроено на использование пользовательских поставщиков членства:

 <membership defaultProvider="MyCustomMembershipProvider">
  <providers>
    <add name="MyCustomMembershipProvider" type="MyNamespace.MyCustomMembershipProvider" connectionStringName="LocalSqlServer"/>
  </providers>
</membership>
<roleManager enabled="true" defaultProvider="MyCustomRoleProvider">
  <providers>
    <add name="MyCustomRoleProvider" type="MyNamespace.MyCustomRoleProvider" connectionStringName="LocalSqlServer"/>
  </providers>
</roleManager>

Отладка выключена:

<compilation debug="false" targetFramework="4.0">

это все люди!

person Community    schedule 07.09.2011