ASP.NET WebForms - завершение сеанса проверки подлинности форм за балансировщиком нагрузки на домашней странице - PullRequest
0 голосов
/ 19 октября 2018

У меня есть приложение .NET 4.6 WebForms, работающее на IIS 10 на 2 веб-серверах с балансировкой нагрузки.При непосредственном доступе к внутреннему серверу, если я вхожу в систему (используя проверку подлинности с помощью форм), тогда мой элемент управления заголовком, который показывает имя пользователя, вошедшего в систему, отображается на всех страницах сайта.

Если я вхожу в систему с домена с балансировкой нагрузки, то на главной странице имя пользователя не отображается и возвращается к сообщению «Пожалуйста, войдите».Нажав на страницу входа, вы увидите «Welcome Back [username]».Если я получаю доступ к внутреннему серверу напрямую, он всегда показывает это сообщение «Добро пожаловать обратно».Это поведение также наблюдается на нашей странице 404/500 - что делается через Web.Config, в элементе system.webServer :

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="503" subStatusCode='-1' />
    <error statusCode="404" path="/ErrorPage.aspx?status=404" responseMode="ExecuteURL" />
    <error statusCode="500" path="/ErrorPage.aspx?status=500" responseMode="ExecuteURL" />
</httpErrors>

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

Опять же, в system.webServer :

  <defaultDocument> 
      <files>
          <clear />
          <add value="Index.aspx" />
          <add value="Default.aspx" />            
      </files>        
  </defaultDocument>

При доступе к этому через внутренний сервер вы можете перейти к пути, который имеет настройку Default.aspx, например, https://site/someFolder Через балансировщик нагрузки необходимо запросить страницу default.aspx.напрямую, например https://site/someFolder/default.aspx

Некоторые из этих путей были настроены для аутентификации с ограничением через web.config, например:

<location path="Admin">
    <system.web>
        <authorization>
            <allow roles="SomeRole" />
            <deny users="*" />
        </authorization>
    </system.web>
</location>

При доступе к ним через внутренний сервер ивы вошли в учетную запись с правильной ролью, вы можете перейти к пути с настройкой Default.aspx, например, https://site/someFolder Через балансировщик нагрузки это вернет вас на страницу входа с настройкой returnURL- так ASPрешил, что вы не вошли в систему. Если вы открываете страницу /default.aspx напрямую, тогда это нормально.Похоже, что сообщение для входа также связано с этой проблемой, например, за LB не обнаружена аутентификация.

Я проверил HTTP-запросы и ответ как от балансировщика нагрузки, так и от бэкэнда - одни и те же файлы cookie отправляются (включая билет для аутентификации)

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

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

<rules>
    <rule name="HTTPS_AlwaysOn" patternSyntax="Wildcard">
        <match url="*" />
        <serverVariables>
            <set name="HTTPS" value="on" />
        </serverVariables>
        <action type="None" />
        <conditions>
            <add input="{HTTP_X_FORWARDED_PROTO}" pattern="https" />
        </conditions>
    </rule>

    <!-- general rewrites/redirects -->

    <rule name="Redirect non-www to www" patternSyntax="Wildcard" stopProcessing="true">
        <match url="*" />
        <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{HTTP_HOST}" pattern="site.domain" />
        </conditions>
        <action type="Redirect" url="https://www.site.domain/{R:0}" />
    </rule>
    <rule name="Convert URLs to lowercase" stopProcessing="true">
        <match url="(.*([A-Z]).*)" ignoreCase="false" />
        <conditions>
            <add input="{URL}" pattern="^.*\.(axd|asmx|css|js|jpg|jpeg|png|gif)$" negate="true" ignoreCase="true" />
            <add input="{URL}" pattern="(assertion)" negate="true" ignoreCase="true" />
        </conditions>
        <action type="Redirect" url="https://{HTTP_HOST}/{ToLower:{R:1}}" redirectType="Permanent" />
    </rule>

И HTTPs обеспечения:

Dim redirect = False

Dim proto = HttpContext.Current.Request.Headers("X-Forwarded-Proto")

If proto IsNot Nothing Then
    redirect = proto.ToLower() <> "https"
Else
    redirect = Not request.IsSecureConnection
End If

If redirect Then
    context.Response.Status = "301 Moved Permanently"
    context.Response.AddHeader("Location", "https://" + request.Url.Host + request.RawUrl)
    context.Response.End()
    Return
End If
...