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

5

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/foo e foo for um diretório, o IIS enviará um redirecionamento 302 "Objeto movido" para http://www.example.com/foo/ como "redirecionamento de cortesia" ( Origem ).

Se você estiver usando o IIS + ARR como proxy reverso com descarregamento de SSL, a solicitação que o nó IIS de backend recebe é sobre http, não https.

Combine esses dois comportamentos e a cortesia do IIS redireciona o SSL. O redirecionamento de cortesia usa o mesmo esquema da solicitação recebida pelo IIS ( Fonte ), http neste caso, em vez de https.

Gostaria de criar uma regra de reconfiguração de saída que compare o URL recebido com o cabeçalho do Local de saída e o reescreva de http para https neste caso:

  • A resposta é um redirecionamento: {RESPONSE_STATUS} é 302
  • A solicitação de entrada foi feita por SSL: {HTTPS} está "on"
  • O URL recebido não termina em uma barra.
  • O cabeçalho do Local de saída termina em uma barra.

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

  • O caminho do cabeçalho de Localização de saída é o mesmo que o URL recebido com uma barra acrescentada.

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 de módulo de regravação de URL), presumivelmente porque estou usando {REQUEST_URI} no padrão. Eu tentei separar a condição em dois e usar grupos de captura, mas isso também não funcionou. Alguma idéia?

<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>
    
por MALfunction84 05.09.2013 / 01:05

1 resposta

3

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

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

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

{provider_name:{server_variable_1}|{server_variable_2}}

O código C # que implementa o provedor fará isso (pseudo-có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";
}

Em seguida, você escreverá mais uma regra para verificar se o valor da variável IsItMatching server é "yes" ou "no".

    
por 09.10.2014 / 05:55