Uma condição de reescrita de URL pode comparar duas variáveis ​​de servidor?

Uma condição de reescrita de URL pode comparar duas variáveis ​​de servidor?

Estou tentando comparar duas variáveis ​​de servidor como parte de uma condição de reescrita de URL. Mas primeiro, algum contexto...

No IIS, se você solicitar http://www.example.com/fooe foofor um diretório, o IIS enviará um redirecionamento 302 "Objeto movido" http://www.example.com/foo/como um "redirecionamento de cortesia" (Fonte).

Se você estiver usando IIS+ARR como proxy reverso com descarregamento de SSL, a solicitação que o nó IIS de back-end recebe será por http, não por https.

Combine esses dois comportamentos e os redirecionamentos de cortesia do IIS eliminarão o SSL. O redirecionamento de cortesia usa o mesmo esquema da solicitação que o IIS recebeu (Fonte), http neste caso em vez de https.

Gostaria de criar uma regra de reescrita de saída que compare o URL de entrada com o cabeçalho Location de saída e reescreva-o de http para https neste caso:

  • A resposta é um redirecionamento: {RESPONSE_STATUS}é 302
  • A solicitação recebida foi via SSL: {HTTPS}está "ativada"
  • O URL recebido não termina com uma barra.
  • O cabeçalho do local de saída termina em uma barra.

Todos os itens acima são tratados na pré-condição. A parte complicada é a última parte:

  • O caminho do cabeçalho Location de saída é o mesmo do URL de entrada com uma barra anexada.

Abaixo está o código que tenho até agora. A pré-condição e a reescrita do cabeçalho funcionam bem. No entanto, a condição causa um erro 500 (erro do módulo de reescrita de URL), provavelmente porque estou usando {REQUEST_URI}no padrão. Tentei separar a condição em duas e usar grupos de captura, mas também não funcionou. Alguma ideia?

<rule name="Fix: Courtesy Redirect + SSL Offloading = SSL dropped" preCondition="Courtesy Redirect Drops SSL" enabled="true">
    <match serverVariable="RESPONSE_LOCATION" pattern="^http://(.+/)$" />
    <conditions>
        <add input="{RESPONSE_LOCATION}" pattern="{REQUEST_URI}/" />
    </conditions>
    <action type="Rewrite" value="https://{R:1}" />
</rule>
<preConditions>
    <preCondition name="Courtesy Redirect Drops SSL">
        <add input="{RESPONSE_STATUS}" pattern="^302$" />
        <add input="{HTTPS}" pattern="^on$" />
        <add input="{REQUEST_URI}" pattern=".*[^/]$" />
        <add input="{RESPONSE_LOCATION}" pattern="^http://.+/$" />
    </preCondition>
</preConditions>

Responder1

Você pode usar umprovedor de reescrita personalizado.Um provedor é um código C# que transforma uma string em outra string. Você pode então usá-lo de maneira semelhante a como usaria o mapa de reescrita:

Você pode escolher um separador que não seja válido em um URL. (Talvez use espaço ou algo parecido. Usarei |para que fique visível neste post, mas você deve escolher alguma outra string.)

Você escreverá uma regra para definir o valor da variável do servidor IsItMatching. O valor da variável do servidor será definido usando seu provedor de reescrita de URL personalizado:

{provider_name:{server_variable_1}|{server_variable_2}}

O código C# que implementa o provedor fará isso (pseudocódigo, sem verificação de erros):

string Rewrite(string input)
{
    string[] inputVariables = input.split(separator);
    if (inputVariables[0] == inputVariables[1] + "/")
        return "yes";
    else
        return "no";
}

Então você escreverá mais uma regra para verificar se o valor da IsItMatchingvariável do servidor é “sim” ou “não”.

informação relacionada