IIS URLrewrite: как сохранить исходное имя хоста для внутренних перенаправлений?

У меня есть веб-приложение, работающее на одном сервере, и я использую IIS с rewriteURL на другом сервере в качестве обратного прокси-сервера.

Я настроил входящие правила так, чтобы адрес обратного прокси переписывался адресом сервера веб-приложений. Это прекрасно работает.

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

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

Я следовал инструкциям здесь https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/modifying-http-response-headers

и мои текущие правила перезаписи выглядят так

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="er-platform" stopProcessing="true">
                    <match url="^er-platform(.*)" />
                    <conditions>
                        <add input="{CACHE_URL}" pattern="^(https?)://" />
                    </conditions>
                    <action type="Rewrite" url="{C:1}://192.168.80.6:8443/{R:0}" />
                    <serverVariables>
                        <set name="ORIGINAL_HOST" value="{HTTP_HOST}" />
                    </serverVariables>
                </rule>
            </rules>
            <outboundRules>
                <rule name="er-platform" preCondition="IsRedirection" enabled="true">
                    <match serverVariable="RESPONSE_LOCATION" pattern="^(https?)://[^/]+/(.*)" />
                    <conditions logicalGrouping="MatchAny">
                        <add input="{ORIGINAL_HOST}" pattern=".+" />
                    </conditions>
                    <action type="Rewrite" value="{R:1}://{ORIGINAL_HOST}/{R:2}" />
                </rule>
                <preConditions>
                    <preCondition name="IsRedirection">
                        <add input="{RESPONSE_STATUS}" pattern="3\d\d" />
                    </preCondition>
                </preConditions>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

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

Спасибо,

Томас


person Thomas    schedule 29.09.2017    source источник


Ответы (1)


Я не думаю, что ваше исходящее правило неверно. У меня есть несколько предположений, почему он терпит неудачу.

Во-первых: правило для входящего трафика должно совпадать с правилом для исходящего трафика. Это связано с тем, что ORIGINAL_HOST фиксируется при выполнении входящего правила. Прямо сейчас ваше входящее правило соответствует URL-адресу ^er-platform(.*). Я собираюсь предположить, что, поскольку это обратный прокси-сервер, он работает, потому что вы не смогли бы начать загрузку, если бы это было не так.

Второе: правило вывода срабатывает только для кода 3xx. Однако это не единственный способ перенаправления. Возможно, вы перенаправляете с помощью JavaScript. Например. `window.location = 'http://wrongaddress'. В этом случае ваше исходящее правило не будет работать.

Дальнейшие действия по отладке: включите ведение журнала для правила для входящего трафика. Флажок IIS Manager Log rewrite URL Ваши журналы будут записываться в %SystemDrive%\inetpub\logs\LogFiles\. Убедитесь, что правило входящего трафика срабатывает.

Проверьте, что происходит в сети: Fiddler — отличный инструмент для понимания того, что на самом деле происходит на проводе. Используйте это, чтобы подтвердить, что правила перезаписи URL-адреса должны срабатывать. т.е. что URL-адрес запроса соответствует ^er-platform(.*) и что код ответа находится в 300-х.

В качестве альтернативы Fiddler вы можете просто использовать вкладку Chrome Developer Tools Network. Установите флажок «Сохранить журнал», чтобы он не очищался после того, как вы были перенаправлены. Убедитесь, что то, что, по вашему мнению, должно происходить, происходит на самом деле.

person Sam Rueby    schedule 01.10.2017
comment
Спасибо за подсказки! Я отследил сеть и обнаружил странное поведение. Как только я запускаю загрузку, приложение отправляет меня к файлу загрузки. Но то, что я получаю, это 401, не авторизованный с локального сервера. Мой текущий сеанс недействителен для этого хоста. Если я создам второй сеанс в своем браузере, используя локальный IP-адрес, я смогу загрузить файл. В этом случае локальный IP-адрес никогда не отображается на вкладке сети. Загрузка происходит с обратного прокси-сервера. Похоже, сеанс обрабатывается неправильно. Это то, что я могу контролировать с помощью IIS? - person Thomas; 02.10.2017
comment
Сервер устанавливает файлы cookie? Возможно из-за неправильного домена или пути, а не внешнего? - person Sam Rueby; 02.10.2017
comment
да, есть куки для сеанса. Я использую внешний домен и правильный путь. - person Thomas; 02.10.2017
comment
Убедитесь, что одни и те же файлы cookie и их значения принимаются/отправляются как в рабочем, так и в нерабочем сценариях. - person Sam Rueby; 02.10.2017
comment
Для нерабочего сценария у меня есть один файл cookie (с хостом, настроенным на внешний домен), для рабочего сценария у меня есть два файла cookie, один из внешнего домена, один для внутреннего IP. Два файла cookie были созданы в отдельных кранах браузера, но совместно используются (по одному на кран), но совместно используются для сеанса браузера. - person Thomas; 02.10.2017
comment
Я думаю, что проблема в куки. идентификатор сеанса неправильно сохраняется за обратным прокси-сервером. Я переформулировал свой вопрос здесь stackoverflow.com/questions/46534125/ . Еще раз спасибо за Ваш ответ. Это очень помогло мне сузить проблему! - person Thomas; 03.10.2017
comment
Я тоже это подозревал. Рад, что смог указать вам правильное направление. - person Sam Rueby; 03.10.2017