Partilhar via


Middleware de Reescrita de URL no ASP.NET Core

Note

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Warning

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 10 deste artigo.

Por Kirk Larkin e Rick Anderson

Este artigo apresenta a reconfiguração de URL com instruções sobre como usar o middleware de reconfiguração de URL em aplicativos ASP.NET Core.

A reconfiguração de URL é o ato de modificar URLs de solicitação com base em uma ou mais regras predefinidas. A reescrita de URL cria uma abstração entre os locais dos recursos e os endereços para que os locais e endereços não fiquem estritamente ligados. A reescrita de URLs é valiosa em vários cenários para:

  • Mova ou substitua recursos do servidor temporária ou permanentemente e mantenha localizadores estáveis para esses recursos.
  • Divida o processamento de solicitações entre diferentes aplicativos ou entre áreas de um aplicativo.
  • Remover, adicionar ou reorganizar segmentos de URL em solicitações de entrada.
  • Otimize URLs públicas para Search Engine Optimization (SEO).
  • Permitir o uso de URLs públicas amigáveis para ajudar os visitantes a prever o conteúdo retornado solicitando um recurso.
  • Redirecionar solicitações inseguras para endpoints seguros.
  • Impeça o hotlinking, em que um site externo usa um ativo estático hospedado em outro site vinculando o ativo em seu próprio conteúdo.

A reconfiguração de URL pode reduzir o desempenho de um aplicativo. Limite o número e a complexidade das regras.

Redirecionamento de URL e reescrita de URL

A diferença na redação entre redirecionamento de URL e regravação de URL é sutil, mas tem implicações importantes para fornecer recursos aos clientes. O Middleware de Reescrita de URL do ASP.NET Core é capaz de atender à necessidade de ambos.

Um redirecionamento de URL envolve uma operação do lado do cliente, onde o cliente é instruído a acessar um recurso em um endereço diferente do que o cliente solicitou originalmente. Isso requer uma viagem de ida e volta ao servidor. A URL de redirecionamento retornada ao cliente aparece na barra de endereço do navegador quando o cliente faz uma nova solicitação para o recurso.

Se /resource for redirecionado para /different-resource, o servidor responde que o cliente deve obter o recurso em /different-resource com um código de status indicando que o redirecionamento é temporário ou permanente.

Um ponto de extremidade do serviço WebAPI foi temporariamente alterado da versão 1 (v1) para a versão 2 (v2) no servidor. Um cliente faz uma solicitação ao serviço no caminho /v1/api da versão 1. O servidor envia de volta uma resposta 302 (Found) com o novo caminho temporário para o serviço na versão 2 /v2/api. O cliente faz uma segunda solicitação ao serviço na URL de redirecionamento. O servidor responde com um código de status 200 (OK).

Ao redirecionar solicitações para uma URL diferente, indique se o redirecionamento é permanente ou temporário especificando o código de status com a resposta:

  • O 301 - Moved Permanently código de status é usado onde o recurso tem uma nova URL permanente e que todas as solicitações futuras para o recurso devem usar a nova URL. O cliente pode armazenar em cache e reutilizar a resposta quando um código de status 301 é recebido.

  • O 302 - Found código de status é usado quando o redirecionamento é temporário ou geralmente sujeito a alterações. O código de status 302 indica ao cliente para não armazenar a URL nem utilizá-la no futuro.

Para obter mais informações sobre códigos de status, consulte RFC 9110: Definições de código de status.

Uma reescrita de URL é uma operação do lado do servidor que fornece um recurso a partir de um endereço de recurso diferente do que o cliente solicitou. Reescrever uma URL não requer uma viagem de ida e volta ao servidor. O URL reescrito não é devolvido ao cliente e não aparece na barra de endereço do navegador.

Se /resource for reescrito para /different-resource, o servidor busca internamente e retorna o recurso em /different-resource.

Embora o cliente possa recuperar o recurso na URL reescrita, o cliente não é informado de que o recurso existe na URL reescrita quando faz sua solicitação e recebe a resposta.

Um ponto de extremidade do serviço WebAPI foi alterado da versão 1 (v1) para a versão 2 (v2) no servidor. Um cliente faz uma solicitação ao serviço no caminho /v1/api da versão 1. A URL da solicitação é reescrita para acessar o serviço no caminho /v2/api da versão 2. O serviço responde ao cliente com um código de status 200 (OK).

Aplicação de exemplo de reescrita de URL

Explore os recursos do URL Rewriting Middleware com o aplicativo de exemplo. O aplicativo aplica regras de redirecionamento e reescrita e mostra a URL redirecionada ou reescrita para vários cenários.

Quando usar o middleware de reescrita de URL

Use o Middleware de reconfiguração de URL quando as seguintes abordagens não forem satisfatórias:

Use o middleware de reescrita de URL quando o aplicativo estiver hospedado no servidor HTTP.sys.

As principais razões para usar as tecnologias de regravação de URL baseadas em servidor no IIS, Apache e Nginx são:

  • O middleware não suporta todos os recursos desses módulos.

    Alguns dos recursos dos módulos de servidor não funcionam com projetos ASP.NET Core, como as restrições IsFile e IsDirectory do módulo de reescrita do IIS. Nesses cenários, use o middleware em vez disso.

  • O desempenho do middleware provavelmente não corresponde ao dos módulos.

    A avaliação comparativa é a única forma de saber com certeza qual a abordagem que mais degrada o desempenho ou se o desempenho degradado é negligenciável.

Extensão e opções

Estabeleça regras de reescrita e redirecionamento de URL criando uma instância da classe RewriteOptions com métodos de extensão para cada uma das regras de reescrita. Encadeie várias regras na ordem em que devem ser processadas. Os RewriteOptions são passados para o URL Rewriting Middleware quando é adicionado ao pipeline de solicitação com UseRewriter:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

No código anterior, MethodRules é uma classe definida pelo usuário. Consulte RewriteRules.cs neste artigo para obter mais informações.

Redirecionar não-www para www

Três opções permitem que o app redirecione solicitações não www para www:

Redirecionamento de URL

Use AddRedirect para redirecionar solicitações. O primeiro parâmetro contém a expressão regular .NET (Regex) para correspondência no caminho da URL de entrada. O segundo parâmetro é a string de substituição. O terceiro parâmetro, se presente, especifica o código de status. Se o código de status não for especificado, o padrão do código de status será 302 - Encontrado, o que indica que o recurso foi movido ou substituído temporariamente.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Em um navegador com as ferramentas de desenvolvedor habilitadas, faça uma solicitação para o aplicativo de exemplo com o caminho /redirect-rule/1234/5678. A expressão regular corresponde ao caminho da solicitação no redirect-rule/(.*), e o caminho é substituído por /redirected/1234/5678. O URL de redirecionamento é enviado de volta ao cliente com um código de status 302 - Encontrado . O navegador faz uma nova solicitação no URL de redirecionamento, que aparece na barra de endereço do navegador. Como nenhuma regra no aplicativo de exemplo corresponde ao URL de redirecionamento:

  • A segunda solicitação recebe uma resposta 200 - OK do aplicativo.
  • O corpo da resposta mostra o URL de redirecionamento.

Uma viagem de ida e volta é feita para o servidor quando uma URL é redirecionada.

Warning

Seja cauteloso ao estabelecer regras de redirecionamento. As regras de redirecionamento são avaliadas em cada solicitação para o aplicativo, inclusive após um redirecionamento. É fácil criar acidentalmente um loop de redirecionamentos infinitos .

A parte da expressão contida entre parênteses é chamada de grupo de captura. O ponto (.) da expressão significa corresponder a qualquer caractere. O asterisco (*) indica corresponder ao caractere anterior zero ou mais vezes. Portanto, os dois últimos segmentos de caminho da URL, 1234/5678, são capturados pelo grupo (.*)de captura. Qualquer valor fornecido na URL de solicitação depois redirect-rule/ é capturado por esse único grupo de captura.

Na cadeia de substituição, os grupos capturados são inseridos na cadeia usando o símbolo de cifrão ($) seguido pelo número de sequência da captura. O primeiro valor do grupo de captura é obtido com $1, o segundo com $2, e eles continuam em sequência para os grupos de captura na expressão regular. Há apenas um grupo capturado na expressão regular da regra de redirecionamento no redirect-rule/(.*), portanto, há apenas um grupo injetado na cadeia de caracteres de substituição, que é $1. Quando a regra é aplicada, o URL torna-se /redirected/1234/5678.

Experimente /redirect-rule/1234/5678 usando as ferramentas do navegador na aba de rede.

Redirecionamento de URL para um endpoint seguro

Use AddRedirectToHttps para redirecionar solicitações HTTP para o mesmo host e caminho usando o protocolo HTTPS. Se o código de status não for fornecido, o middleware assume como padrão 302 - Encontrado. Se a porta não for fornecida:

  • O middleware assume como null padrão.
  • O esquema muda para https (protocolo HTTPS) e o cliente acessa o recurso na porta 443.

O exemplo a seguir mostra como definir o código de status para 301 - Moved Permanently e alterar a porta para a porta HTTPS usada por Kestrel no localhost. Na produção, a porta HTTPS é definida como null:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

int? localhostHTTPSport = null;
if (app.Environment.IsDevelopment())
{
    localhostHTTPSport = Int32.Parse(Environment.GetEnvironmentVariable(
                   "ASPNETCORE_URLS")!.Split(new Char[] { ':', ';' })[2]);
}

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        // localhostHTTPport not needed for production, used only with localhost.
        .AddRedirectToHttps(301, localhostHTTPSport)
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Use AddRedirectToHttpsPermanent para redirecionar solicitações inseguras para o mesmo host e caminho com o protocolo HTTPS seguro na porta 443. O middleware define o código de status como 301 - Moved Permanently.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Note

Ao redirecionar para um ponto de extremidade seguro sem a necessidade de regras de redirecionamento adicionais, recomendamos o uso do middleware de redirecionamento HTTPS. Para obter mais informações, consulte Impor HTTPS.

O aplicativo de exemplo demonstra como usar AddRedirectToHttps ou AddRedirectToHttpsPermanent. Faça uma solicitação HTTP insegura para o aplicativo em http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz. Ao testar o redirecionamento de HTTP para HTTPS com localhost:

  • Use a URL HTTP, que tem uma porta diferente da URL HTTPS. O URL HTTP está no Properties/launchSettings.json arquivo.
  • A remoção de s de https://localhost/{port} falha porque o localhost não responde no protocolo HTTP na porta destinada ao HTTPS.

A imagem a seguir mostra as ferramentas do navegador F12 de uma solicitação para http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz usando o código anterior:

Janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas: Adicionar redirecionamento para HTTPS

reescrita de URL

Use AddRewrite para criar uma regra para reescrever URLs. O primeiro parâmetro contém a expressão regular para correspondência no caminho da URL de entrada. O segundo parâmetro é a string de substituição. O terceiro parâmetro, skipRemainingRules: {true|false}, indica ao middleware se deve ou não ignorar regras de reescrita adicionais se a regra atual for aplicada.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Experimente fazer o pedido para: https://redirect6.azurewebsites.net/rewrite-rule/1234/5678

O cursor (^) no início da expressão significa que a correspondência começa no início do caminho da URL.

No exemplo anterior com a regra de redirecionamento, redirect-rule/(.*), não há circunflexo (^) no início da expressão regular. Portanto, quaisquer caracteres podem preceder redirect-rule/ no caminho para uma partida bem-sucedida.

Path Match
/redirect-rule/1234/5678 Yes
/my-cool-redirect-rule/1234/5678 Yes
/anotherredirect-rule/1234/5678 Yes

A regra de reescrita, ^rewrite-rule/(\d+)/(\d+), só corresponde aos caminhos se eles começarem com rewrite-rule/. Na tabela a seguir, observe a diferença na correspondência.

Path Match
/rewrite-rule/1234/5678 Yes
/my-cool-rewrite-rule/1234/5678 No
/anotherrewrite-rule/1234/5678 No

Seguindo a ^rewrite-rule/ parte da expressão, há dois grupos de captura, (\d+)/(\d+). O \d significa corresponde a um dígito (número). O sinal de adição (+) significa corresponder a um ou mais dos caracteres anteriores. Portanto, a URL deve conter um número seguido por uma barra frontal seguida por outro número. Esses grupos de captura são injetados na URL reescrita como $1 e $2. A sequência de substituição da regra de reescrita coloca os grupos capturados na sequência de consulta. O caminho /rewrite-rule/1234/5678 solicitado é reescrito para retornar o recurso em /rewritten?var1=1234&var2=5678. Se uma cadeia de caracteres de consulta estiver presente na solicitação original, ela será preservada quando a URL for reescrita.

Não há ida e volta ao servidor para retornar o recurso. Se o recurso existir, ele será buscado e retornado ao cliente com um código de status 200 - OK . Como o cliente não é redirecionado, o URL na barra de endereço do navegador não é alterado. Os clientes não conseguem detetar que ocorreu uma operação de reescrita de URL no servidor.

Dicas de desempenho para regravação e redirecionamento de URL

Para uma resposta mais rápida:

  • Ordene a reescrita de regras da regra com correspondência mais frequente para a regra com correspondência menos frequente.
  • Use skipRemainingRules: true sempre que possível, pois as regras de correspondência são computacionalmente caras e aumentam o tempo de resposta do aplicativo. Ignore o processamento das regras restantes quando ocorrer uma correspondência e nenhum processamento de regra adicional for necessário.

Warning

Um usuário mal-intencionado pode fornecer informações caras para RegularExpressions processar para causar um ataque de negação de serviço. APIs do ASP.NET Core que usam RegularExpressions instituem um tempo limite. Por exemplo, o tempo limite Regex (_regexTimeout) das classes RedirectRule e RewriteRule é configurado para um segundo.

Note

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Apache mod_rewrite (módulo de reescrita do Apache)

Aplique as regras do Apache mod_rewrite com AddApacheModRewrite. Verifique se o arquivo de regras é implantado com o aplicativo. Para obter mais informações e exemplos de regras de mod_rewrite, consulte Apache mod_rewrite.

A StreamReader é usado para ler as regras do arquivo de regras ApacheModRewrite.txt :

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

O aplicativo de exemplo redireciona solicitações de /apache-mod-rules-redirect/(.\*) para /redirected?id=$1. O código de status da resposta é 302 - Encontrado.

# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]

Experimente fazer o pedido para: https://redirect6.azurewebsites.net/apache-mod-rules-redirect/1234

O middleware Apache suporta as seguintes variáveis de servidor Apache mod_rewrite:

  • CONN_REMOTE_ADDR
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_FORWARDED
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_USER_AGENT
  • HTTPS
  • IPV6
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_METHOD
  • REQUEST_SCHEME
  • REQUEST_URI
  • SCRIPT_FILENAME
  • SERVER_ADDR
  • SERVER_PORT
  • SERVER_PROTOCOL
  • TIME
  • TIME_DAY
  • TIME_HOUR
  • TIME_MIN
  • TIME_MON
  • TIME_SEC
  • TIME_WDAY
  • TIME_YEAR

Note

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Regras do módulo de reconfiguração de URL do IIS

Para usar o mesmo conjunto de regras que se aplica ao Módulo de Reconfiguração de URL do IIS, use AddIISUrlRewrite. Verifique se o arquivo de regras é implantado com o aplicativo. Não direcione o middleware para usar o arquivo web.config do aplicativo durante a execução no Windows Server IIS. Com o IIS, essas regras devem ser armazenadas fora do arquivo de web.config do aplicativo para evitar conflitos com o módulo de regravação do IIS. Para obter mais informações e exemplos de regras do Módulo de Reescrita de URL do IIS, consulte Usando o Módulo de Regravação de URL 2.0 e Referência de Configuração do Módulo de Regravação de URL.

A StreamReader é usado para ler as regras do IISUrlRewrite.xml arquivo de regras:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

O aplicativo de exemplo reescreve solicitações de /iis-rules-rewrite/(.*) para /rewritten?id=$1. A resposta é enviada ao cliente com um código de status 200 - OK .

<rewrite>
  <rules>
    <rule name="Rewrite segment to id querystring" stopProcessing="true">
      <match url="^iis-rules-rewrite/(.*)$" />
      <action type="Rewrite" url="rewritten?id={R:1}" appendQueryString="false"/>
    </rule>
  </rules>
</rewrite>

Experimente fazer o pedido para: https://redirect6.azurewebsites.net/iis-rules-rewrite/xyz

Aplicativos que têm um Módulo de Regravação do IIS ativo com regras no nível do servidor configuradas que afetam o aplicativo de maneiras indesejáveis:

Funcionalidades não suportadas

O middleware não suporta os seguintes recursos do módulo de regravação de URL do IIS:

  • Regras de saída
  • Variáveis de servidor personalizadas
  • Wildcards
  • LogRewrittenUrl

Variáveis de servidor suportadas

O middleware suporta as seguintes variáveis de servidor do Módulo de Reescrita de URL do IIS:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_URL
  • HTTP_USER_AGENT
  • HTTPS
  • LOCAL_ADDR
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_URI

Note

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).

IFileProvider pode ser obtido através de um PhysicalFileProvider. Esta abordagem pode fornecer maior flexibilidade para a localização dos arquivos de regras de reescrita. Certifique-se de que os arquivos de regras de regravação sejam implantados no servidor no caminho fornecido.

var fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());

Regra baseada em método

Use Add para implementar a lógica de regra personalizada em um método. Add expõe o RewriteContext, que disponibiliza o HttpContext para uso em métodos de redirecionamento. A propriedade RewriteContext.Result determina como é tratado o processamento adicional do pipeline. Defina o valor como um dos RuleResult campos descritos na tabela a seguir.

Reescrever resultado de contexto Action
RuleResult.ContinueRules (padrão) Continuar a aplicar regras.
RuleResult.EndResponse Pare de aplicar regras e envie a resposta.
RuleResult.SkipRemainingRules Pare de aplicar regras e envie o contexto para o próximo middleware.
using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

O aplicativo de exemplo demonstra um método que redireciona solicitações para caminhos que terminam com .xml. Quando é apresentado um pedido para /file.xml:

  • O pedido é redirecionado para /xmlfiles/file.xml
  • O código de status é definido como 301 - Moved Permanently. Quando o navegador faz uma nova solicitação para /xmlfiles/file.xml, o Static File Middleware serve diretamente o arquivo para o cliente a partir da pasta wwwroot/xmlfiles. Para um redirecionamento, defina explicitamente o código de status da resposta. Caso contrário, um código de status 200 - OK será retornado e o redirecionamento não ocorrerá no cliente.

RewriteRules.cs:

public static void RedirectXmlFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    // Because the client is redirecting back to the same app, stop 
    // processing if the request has already been redirected.
    if (request.Path.StartsWithSegments(new PathString("/xmlfiles")) ||
        request.Path.Value==null)
    {
        return;
    }

    if (request.Path.Value.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
    {
        var response = context.HttpContext.Response;
        response.StatusCode = (int) HttpStatusCode.MovedPermanently;
        context.Result = RuleResult.EndResponse;
        response.Headers[HeaderNames.Location] = 
            "/xmlfiles" + request.Path + request.QueryString;
    }
}

Essa abordagem também pode reescrever solicitações. A aplicação de exemplo demonstra reescrever o caminho para qualquer solicitação de arquivo de texto para servir o ficheiro de texto file.txt a partir da pasta wwwroot. O Middleware de Arquivo Estático serve o arquivo com base no caminho de solicitação atualizado:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

RewriteRules.cs:

public static void RewriteTextFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    if (request.Path.Value != null &&
        request.Path.Value.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
        context.Result = RuleResult.SkipRemainingRules;
        request.Path = "/file.txt";
    }
}

Regra baseada em IRule

Use Add para usar a lógica de regra em uma classe que implementa a IRule interface. IRule proporciona maior flexibilidade em relação ao uso da abordagem de regra baseada em método. A classe de implementação pode incluir um construtor que permite passar parâmetros para o ApplyRule método.

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)
        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Os valores dos parâmetros no aplicativo de exemplo para o extension e o newPath são verificados para atender a várias condições. O extension deve conter um valor, e o valor deve ser .png, .jpgou .gif. Se o newPath não for válido, uma ArgumentException é gerada. Se for feita uma solicitação para image.png, a solicitação será redirecionada para /png-images/image.png. Se for feita uma solicitação para image.jpg, a solicitação será redirecionada para /jpg-images/image.jpg. O código de status é definido como 301 - Moved Permanently, e o context.Result é definido para parar o processamento das regras e enviar a resposta.

public class RedirectImageRequests : IRule
{
    private readonly string _extension;
    private readonly PathString _newPath;

    public RedirectImageRequests(string extension, string newPath)
    {
        if (string.IsNullOrEmpty(extension))
        {
            throw new ArgumentException(nameof(extension));
        }

        if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif)$"))
        {
            throw new ArgumentException("Invalid extension", nameof(extension));
        }

        if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))
        {
            throw new ArgumentException("Invalid path", nameof(newPath));
        }

        _extension = extension;
        _newPath = new PathString(newPath);
    }

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        // Because we're redirecting back to the same app, stop 
        // processing if the request has already been redirected
        if (request.Path.StartsWithSegments(new PathString(_newPath)) ||
            request.Path.Value == null)
        {
            return;
        }

        if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.HttpContext.Response;
            response.StatusCode = (int) HttpStatusCode.MovedPermanently;
            context.Result = RuleResult.EndResponse;
            response.Headers[HeaderNames.Location] = 
                _newPath + request.Path + request.QueryString;
        }
    }
}

Try:

  • Pedido PNG: https://redirect6.azurewebsites.net/image.png
  • Solicitação JPG: https://redirect6.azurewebsites.net/image.jpg

Exemplos de Regex

Goal Regex String &
Exemplo de correspondência
String de substituição &
Exemplo de saída
Reescrever caminho em querystring ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Remover barra final ^path2/(.*)/$
/path2/xyz/
$1
/path2/xyz
Impor barra final ^path3/(.*[^/])$
/path3/xyz
$1/
/path3/xyz/
Evite reescrever solicitações específicas ^(.*)(?<!\.axd)$ ou
^(?!.*\.axd$)(.*)$
Sim: /path4/resource.htm
Não: /path4/resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
Reorganizar segmentos de URL path5/(.*)/(.*)/(.*)
path5/1/2/3
path5/$3/$2/$1
path5/3/2/1
Substituir um segmento de URL ^path6/(.*)/segment2/(.*)
^path6/segment1/segment2/segment3
path6/$1/replaced/$2
/path6/segment1/replaced/segment3

Os links na tabela anterior usam o seguinte código implantado no Azure:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

using (StreamReader apacheModRewriteStreamReader =
    File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
    File.OpenText("IISUrlRewrite.xml"))
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent()
        .AddRedirect("redirect-rule/(.*)", "redirected/$1")
        .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2",
            skipRemainingRules: true)

        // Rewrite path to QS.
        .AddRewrite(@"^path/(.*)/(.*)", "path?var1=$1&var2=$2",
            skipRemainingRules: true)
        // Skip trailing slash.
        .AddRewrite(@"^path2/(.*)/$", "path2/$1",
            skipRemainingRules: true)
         // Enforce trailing slash.
         .AddRewrite(@"^path3/(.*[^/])$", "path3/$1/",
            skipRemainingRules: true)
         // Avoid rewriting specific requests.
         .AddRewrite(@"^path4/(.*)(?<!\.axd)$", "rewritten/$1",
            skipRemainingRules: true)
         // Rearrange URL segments
         .AddRewrite(@"^path5/(.*)/(.*)/(.*)", "path5/$3/$2/$1",
            skipRemainingRules: true)
          // Replace a URL segment
          .AddRewrite(@"^path6/(.*)/segment2/(.*)", "path6/$1/replaced/$2",
            skipRemainingRules: true)

        .AddApacheModRewrite(apacheModRewriteStreamReader)
        .AddIISUrlRewrite(iisUrlRewriteStreamReader)
        .Add(MethodRules.RedirectXmlFileRequests)
        .Add(MethodRules.RewriteTextFileRequests)
        .Add(new RedirectImageRequests(".png", "/png-images"))
        .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

    app.UseRewriter(options);
}

app.UseStaticFiles();

app.Run(context => context.Response.WriteAsync(
    $"Rewritten or Redirected Url: " +
    $"{context.Request.Path + context.Request.QueryString}"));

app.Run();

Na maioria dos exemplos de expressão regular anteriores, o literal path é usado para criar regras de regravação testáveis exclusivas para o exemplo implantado. Normalmente, a expressão regular não incluiria path. Por exemplo, consulte esta tabela de exemplos de expressões regulares .

Este documento apresenta a reconfiguração de URL com instruções sobre como usar o middleware de reconfiguração de URL em aplicativos ASP.NET Core.

A reconfiguração de URL é o ato de modificar URLs de solicitação com base em uma ou mais regras predefinidas. A reescrita de URL cria uma abstração entre os locais dos recursos e os endereços para que os locais e endereços não fiquem estritamente ligados. A reescrita de URLs é valiosa em vários cenários para:

  • Mova ou substitua recursos do servidor temporária ou permanentemente e mantenha localizadores estáveis para esses recursos.
  • Divida o processamento de solicitações entre diferentes aplicativos ou entre áreas de um aplicativo.
  • Remover, adicionar ou reorganizar segmentos de URL em solicitações de entrada.
  • Otimize URLs públicas para Search Engine Optimization (SEO).
  • Permitir o uso de URLs públicas amigáveis para ajudar os visitantes a prever o conteúdo retornado solicitando um recurso.
  • Redirecionar solicitações inseguras para endpoints seguros.
  • Impeça o hotlinking, em que um site externo usa um ativo estático hospedado em outro site vinculando o ativo em seu próprio conteúdo.

Note

A reconfiguração de URL pode reduzir o desempenho de um aplicativo. Sempre que possível, limitar o número e a complexidade das regras.

Visualizar ou descarregar amostra de código (como descarregar)

Redirecionamento de URL e reescrita de URL

A diferença na redação entre redirecionamento de URL e regravação de URL é sutil, mas tem implicações importantes para fornecer recursos aos clientes. O Middleware de Reescrita de URL do ASP.NET Core é capaz de atender à necessidade de ambos.

Um redirecionamento de URL envolve uma operação do lado do cliente, onde o cliente é instruído a acessar um recurso em um endereço diferente do que o cliente solicitou originalmente. Isso requer uma viagem de ida e volta ao servidor. A URL de redirecionamento retornada ao cliente aparece na barra de endereço do navegador quando o cliente faz uma nova solicitação para o recurso.

Se /resource for redirecionado para /different-resource, o servidor responde que o cliente deve obter o recurso em /different-resource com um código de status indicando que o redirecionamento é temporário ou permanente.

Um ponto de extremidade do serviço WebAPI foi temporariamente alterado da versão 1 (v1) para a versão 2 (v2) no servidor. Um cliente faz uma solicitação ao serviço no caminho /v1/api da versão 1. O servidor envia de volta uma resposta 302 (Found) com o novo caminho temporário para o serviço na versão 2 /v2/api. O cliente faz uma segunda solicitação ao serviço na URL de redirecionamento. O servidor responde com um código de status 200 (OK).

Ao redirecionar solicitações para uma URL diferente, indique se o redirecionamento é permanente ou temporário especificando o código de status com a resposta:

  • O 301 - Moved Permanently código de status é usado quando o recurso tem uma URL nova e permanente e você deseja instruir o cliente que todas as solicitações futuras para o recurso devem usar a nova URL. O cliente pode armazenar em cache e reutilizar a resposta quando um código de status 301 é recebido.

  • O código de status 302 - Encontrado é usado quando o redirecionamento é temporário ou geralmente sujeito a alterações. O código de status 302 indica ao cliente para não armazenar a URL nem utilizá-la no futuro.

Para obter mais informações sobre códigos de status, consulte RFC 9110: Definições de código de status.

Uma reescrita de URL é uma operação do lado do servidor que fornece um recurso a partir de um endereço de recurso diferente do que o cliente solicitou. Reescrever uma URL não requer uma viagem de ida e volta ao servidor. O URL reescrito não é devolvido ao cliente e não aparece na barra de endereço do navegador.

Se /resource for reescrito para /different-resource, o servidor busca internamente e retorna o recurso em /different-resource.

Embora o cliente possa recuperar o recurso na URL reescrita, o cliente não é informado de que o recurso existe na URL reescrita quando faz sua solicitação e recebe a resposta.

Um ponto de extremidade do serviço WebAPI foi alterado da versão 1 (v1) para a versão 2 (v2) no servidor. Um cliente faz uma solicitação ao serviço no caminho /v1/api da versão 1. A URL da solicitação é reescrita para acessar o serviço no caminho /v2/api da versão 2. O serviço responde ao cliente com um código de status 200 (OK).

Aplicação de exemplo de reescrita de URL

Você pode explorar os recursos do URL Rewriting Middleware com o aplicativo de exemplo. O aplicativo aplica regras de redirecionamento e reescrita e mostra a URL redirecionada ou reescrita para vários cenários.

Quando usar o middleware de reescrita de URL

Use o middleware de reconfiguração de URL quando não conseguir usar as seguintes abordagens:

Use o middleware de reescrita de URL quando o aplicativo estiver hospedado no servidor HTTP.sys.

As principais razões para usar as tecnologias de regravação de URL baseadas em servidor no IIS, Apache e Nginx são:

  • O middleware não suporta todos os recursos desses módulos.

    Alguns dos recursos dos módulos de servidor não funcionam com projetos ASP.NET Core, como as restrições IsFile e IsDirectory do módulo de reescrita do IIS. Nesses cenários, use o middleware em vez disso.

  • O desempenho do middleware provavelmente não corresponde ao dos módulos.

    O benchmarking é a única maneira de saber com certeza qual abordagem degrada mais o desempenho ou se o desempenho degradado é insignificante.

Package

O Middleware de Reconfiguração de URL é fornecido pelo pacote Microsoft.AspNetCore.Rewrite , que está implicitamente incluído nos aplicativos ASP.NET Core.

Extensão e opções

Estabeleça regras de reescrita e redirecionamento de URL criando uma instância da classe RewriteOptions com métodos de extensão para cada uma das suas regras de reescrita. Encadeie várias regras na ordem em que você gostaria que fossem processadas. Os RewriteOptions são passados para o URL Rewriting Middleware quando é adicionado ao pipeline de solicitação com UseRewriter:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Redirecionar não-www para www

Três opções permitem que o app redirecione solicitações não www para www:

  • AddRedirectToWwwPermanent: Redirecione permanentemente o pedido para o subdomínio www se o pedido não for www. Esta função redireciona com um código de estado Status308PermanentRedirect.

  • AddRedirectToWww: Redirecionar a solicitação para o subdomínio www se a solicitação de entrada não for www. Redireciona com o código de estado Status307TemporaryRedirect. Uma sobrecarga permite que você forneça o código de status para a resposta. Use um campo da StatusCodes classe para uma atribuição de código de status.

Redirecionamento de URL

Use AddRedirect para redirecionar solicitações. O primeiro parâmetro contém o seu Regex para correspondência com o caminho da URL de entrada. O segundo parâmetro é a string de substituição. O terceiro parâmetro, se presente, especifica o código de status. Se você não especificar o código de status, o padrão do código de status será 302 - Encontrado, o que indica que o recurso foi movido ou substituído temporariamente.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Em um navegador com as ferramentas de desenvolvedor habilitadas, faça uma solicitação para o aplicativo de exemplo com o caminho /redirect-rule/1234/5678. O regex corresponde ao caminho da solicitação no redirect-rule/(.*), e o caminho é substituído por /redirected/1234/5678. O URL de redirecionamento é enviado de volta ao cliente com um código de status 302 - Encontrado . O navegador faz uma nova solicitação no URL de redirecionamento, que aparece na barra de endereço do navegador. Como nenhuma regra no aplicativo de exemplo corresponde ao URL de redirecionamento:

  • A segunda solicitação recebe uma resposta 200 - OK do aplicativo.
  • O corpo da resposta mostra o URL de redirecionamento.

Uma viagem de ida e volta é feita para o servidor quando uma URL é redirecionada.

Warning

Seja cauteloso ao estabelecer regras de redirecionamento. As regras de redirecionamento são avaliadas em cada solicitação para o aplicativo, inclusive após um redirecionamento. É fácil criar acidentalmente um loop de redirecionamentos infinitos.

Pedido Original: /redirect-rule/1234/5678

Janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas: Adicionar redirecionamento

A parte da expressão contida entre parênteses é chamada de grupo de captura. O ponto (.) da expressão significa corresponder a qualquer caractere. O asterisco (*) indica corresponder ao caractere anterior zero ou mais vezes. Portanto, os dois últimos segmentos de caminho da URL, 1234/5678, são capturados pelo grupo (.*)de captura. Qualquer valor fornecido na URL de solicitação depois redirect-rule/ é capturado por esse único grupo de captura.

Na cadeia de substituição, os grupos capturados são inseridos na cadeia usando o símbolo de cifrão ($) seguido pelo número de sequência da captura. O primeiro valor do grupo de captura é obtido com $1, o segundo com $2, e eles continuam em sequência para os grupos de captura em seu regex. Há apenas um grupo capturado no regex da regra de redirecionamento no aplicativo de exemplo, portanto, há apenas um grupo injetado na cadeia de caracteres de substituição, que é $1. Quando a regra é aplicada, o URL torna-se /redirected/1234/5678.

Redirecionamento de URL para um endpoint seguro

Use AddRedirectToHttps para redirecionar solicitações HTTP para o mesmo host e caminho usando o protocolo HTTPS. Se o código de status não for fornecido, o middleware assume como padrão 302 - Encontrado. Se a porta não for fornecida:

  • O middleware assume como null padrão.
  • O esquema muda para https (protocolo HTTPS) e o cliente acessa o recurso na porta 443.

O exemplo a seguir mostra como definir o código de status como 301 - Moved Permanently e como alterar a porta para 5001.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttps(301, 5001);

    app.UseRewriter(options);
}

Use AddRedirectToHttpsPermanent para redirecionar solicitações inseguras para o mesmo host e caminho com o protocolo HTTPS seguro na porta 443. O middleware define o código de status como 301 - Moved Permanently.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent();

    app.UseRewriter(options);
}

Note

Ao redirecionar para um ponto de extremidade seguro sem a necessidade de regras de redirecionamento adicionais, recomendamos o uso do middleware de redirecionamento HTTPS. Para obter mais informações, consulte o tópico Enforce HTTPS .

O aplicativo de exemplo é capaz de demonstrar como usar AddRedirectToHttps ou AddRedirectToHttpsPermanent. Adicione o método de extensão ao RewriteOptions. Faça uma solicitação insegura para o aplicativo em qualquer URL. Ignore o aviso de segurança do navegador de que o certificado autoassinado não é confiável ou crie uma exceção para confiar no certificado.

Pedido original utilizando AddRedirectToHttps(301, 5001): http://localhost:5000/secure

Janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas: Adicionar redirecionamento para HTTPS

Pedido original utilizando AddRedirectToHttpsPermanent: http://localhost:5000/secure

Janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas: Adicionar redirecionamento para HTTPS permanente

reescrita de URL

Use AddRewrite para criar uma regra para reescrever URLs. O primeiro parâmetro contém o regex para correspondência no caminho de URL de entrada. O segundo parâmetro é a string de substituição. O terceiro parâmetro, skipRemainingRules: {true|false}, indica ao middleware se deve ou não ignorar regras de reescrita adicionais se a regra atual for aplicada.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Pedido Original: /rewrite-rule/1234/5678

Janela do navegador com ferramentas de desenvolvedor rastreando a solicitação e a resposta: Adicionar reescrita

O quilate (^) no início da expressão significa que a correspondência começa no início do caminho da URL.

No exemplo anterior com a regra de redirecionamento, redirect-rule/(.*), não há circunflexo (^) no início do regex. Portanto, quaisquer caracteres podem preceder redirect-rule/ no caminho para uma partida bem-sucedida.

Path Match
/redirect-rule/1234/5678 Yes
/my-cool-redirect-rule/1234/5678 Yes
/anotherredirect-rule/1234/5678 Yes

A regra de reescrita, ^rewrite-rule/(\d+)/(\d+), só corresponde aos caminhos se eles começarem com rewrite-rule/. Na tabela a seguir, observe a diferença na correspondência.

Path Match
/rewrite-rule/1234/5678 Yes
/my-cool-rewrite-rule/1234/5678 No
/anotherrewrite-rule/1234/5678 No

Seguindo a ^rewrite-rule/ parte da expressão, há dois grupos de captura, (\d+)/(\d+). O \d significa corresponde a um dígito (número). O sinal de adição (+) significa corresponder a um ou mais dos caracteres anteriores. Portanto, a URL deve conter um número seguido por uma barra frontal seguida por outro número. Esses grupos de captura são injetados na URL reescrita como $1 e $2. A sequência de substituição da regra de reescrita coloca os grupos capturados na sequência de consulta. O caminho solicitado de /rewrite-rule/1234/5678 é reescrito para obter o recurso em /rewritten?var1=1234&var2=5678. Se uma cadeia de caracteres de consulta estiver presente na solicitação original, ela será preservada quando a URL for reescrita.

Não há ida e volta ao servidor para obter o recurso. Se o recurso existir, ele será buscado e retornado ao cliente com um código de status 200 - OK . Como o cliente não é redirecionado, o URL na barra de endereço do navegador não é alterado. Os clientes não conseguem detetar que ocorreu uma operação de reescrita de URL no servidor.

Note

Use skipRemainingRules: true sempre que possível, pois as regras de correspondência são computacionalmente caras e aumentam o tempo de resposta do aplicativo. Para obter a resposta mais rápida do aplicativo:

  • Ordene a reescrita de regras da regra com correspondência mais frequente para a regra com correspondência menos frequente.
  • Ignore o processamento das regras restantes quando ocorrer uma correspondência e nenhum processamento de regra adicional for necessário.

Apache mod_rewrite (módulo de reescrita do Apache)

Aplique as regras do Apache mod_rewrite com AddApacheModRewrite. Verifique se o arquivo de regras é implantado com o aplicativo. Para obter mais informações e exemplos de regras de mod_rewrite, consulte Apache mod_rewrite.

A StreamReader é usado para ler as regras do arquivo de regras ApacheModRewrite.txt :

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

O aplicativo de exemplo redireciona solicitações de /apache-mod-rules-redirect/(.\*) para /redirected?id=$1. O código de status da resposta é 302 - Encontrado.

# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]

Pedido Original: /apache-mod-rules-redirect/1234

Adicionar redirecionamento do módulo Apache: Janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas

O middleware suporta as seguintes variáveis de servidor Apache mod_rewrite:

  • CONN_REMOTE_ADDR
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_FORWARDED
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_USER_AGENT
  • HTTPS
  • IPV6
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_METHOD
  • REQUEST_SCHEME
  • REQUEST_URI
  • SCRIPT_FILENAME
  • SERVER_ADDR
  • SERVER_PORT
  • SERVER_PROTOCOL
  • TIME
  • TIME_DAY
  • TIME_HOUR
  • TIME_MIN
  • TIME_MON
  • TIME_SEC
  • TIME_WDAY
  • TIME_YEAR

Regras do módulo de reconfiguração de URL do IIS

Para usar o mesmo conjunto de regras que se aplica ao Módulo de Reconfiguração de URL do IIS, use AddIISUrlRewrite. Verifique se o arquivo de regras é implantado com o aplicativo. Não direcione o middleware para usar o arquivo web.config do aplicativo durante a execução no Windows Server IIS. Com o IIS, essas regras devem ser armazenadas fora do arquivo de web.config do aplicativo para evitar conflitos com o módulo de regravação do IIS. Para obter mais informações e exemplos de regras do Módulo de Reescrita de URL do IIS, consulte Usando o Módulo de Regravação de URL 2.0 e Referência de Configuração do Módulo de Regravação de URL.

A StreamReader é usado para ler as regras do IISUrlRewrite.xml arquivo de regras:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

O aplicativo de exemplo reescreve solicitações de /iis-rules-rewrite/(.*) para /rewritten?id=$1. A resposta é enviada ao cliente com um código de status 200 - OK .

<rewrite>
  <rules>
    <rule name="Rewrite segment to id querystring" stopProcessing="true">
      <match url="^iis-rules-rewrite/(.*)$" />
      <action type="Rewrite" url="rewritten?id={R:1}" appendQueryString="false"/>
    </rule>
  </rules>
</rewrite>

Pedido Original: /iis-rules-rewrite/1234

Janela do navegador com ferramentas de desenvolvedor rastreando a solicitação e a resposta: Adicionar reconfiguração de URL do IIS

Se você tiver um Módulo de Regravação do IIS ativo com regras de nível de servidor configuradas que afetariam seu aplicativo de maneiras indesejáveis, poderá desabilitar o Módulo de Regravação do IIS para um aplicativo. Para obter mais informações, consulte Desabilitando módulos do IIS.

Funcionalidades não suportadas

O middleware não suporta os seguintes recursos do módulo de regravação de URL do IIS:

  • Regras de saída
  • Variáveis de servidor personalizadas
  • Wildcards
  • LogRewrittenUrl

Variáveis de servidor suportadas

O middleware suporta as seguintes variáveis de servidor do Módulo de Reescrita de URL do IIS:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_URL
  • HTTP_USER_AGENT
  • HTTPS
  • LOCAL_ADDR
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_URI

Note

Você também pode obter um IFileProvider via PhysicalFileProvider. Essa abordagem pode fornecer maior flexibilidade para o local de seus arquivos de regras de reescrita. Certifique-se de que seus arquivos de regras de reescrita sejam implantados no servidor no caminho fornecido.

PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());

Regra baseada em método

Use Add para implementar sua própria lógica de regra em um método. Add expõe o RewriteContext, que disponibiliza o HttpContext para uso em seu método. O RewriteContext.Result determina como o processamento de pipeline adicional é manipulado. Defina o valor como um dos RuleResult campos descritos na tabela a seguir.

Reescrever resultado de contexto Action
RuleResult.ContinueRules (padrão) Continuar a aplicar regras.
RuleResult.EndResponse Pare de aplicar regras e envie a resposta.
RuleResult.SkipRemainingRules Pare de aplicar regras e envie o contexto para o próximo middleware.
public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

O aplicativo de exemplo demonstra um método que redireciona solicitações para caminhos que terminam com .xml. Se for feita uma solicitação para /file.xml, a solicitação será redirecionada para /xmlfiles/file.xml. O código de status é definido como 301 - Moved Permanently. Quando o navegador faz uma nova solicitação para /xmlfiles/file.xml, o Static File Middleware serve diretamente o arquivo para o cliente a partir da pasta wwwroot/xmlfiles. Para um redirecionamento, defina explicitamente o código de status da resposta. Caso contrário, um código de status 200 - OK será retornado e o redirecionamento não ocorrerá no cliente.

RewriteRules.cs:

public static void RedirectXmlFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    // Because the client is redirecting back to the same app, stop 
    // processing if the request has already been redirected.
    if (request.Path.StartsWithSegments(new PathString("/xmlfiles")))
    {
        return;
    }

    if (request.Path.Value.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
    {
        var response = context.HttpContext.Response;
        response.StatusCode = (int) HttpStatusCode.MovedPermanently;
        context.Result = RuleResult.EndResponse;
        response.Headers[HeaderNames.Location] = 
            "/xmlfiles" + request.Path + request.QueryString;
    }
}

Essa abordagem também pode reescrever solicitações. A aplicação de exemplo demonstra reescrever o caminho para qualquer solicitação de arquivo de texto para servir o ficheiro de texto file.txt a partir da pasta wwwroot. O Middleware de Arquivo Estático serve o arquivo com base no caminho de solicitação atualizado:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

RewriteRules.cs:

public static void RewriteTextFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    if (request.Path.Value.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
        context.Result = RuleResult.SkipRemainingRules;
        request.Path = "/file.txt";
    }
}

Regra baseada em IRule

Use Add para usar a lógica de regra em uma classe que implementa a IRule interface. IRule proporciona maior flexibilidade em relação ao uso da abordagem de regra baseada em método. Sua classe de implementação pode incluir um construtor que permite que você possa passar parâmetros para o ApplyRule método.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Os valores dos parâmetros no aplicativo de exemplo para o extension e o newPath são verificados para atender a várias condições. O extension deve conter um valor, e o valor deve ser .png, .jpgou .gif. Se o newPath não for válido, uma ArgumentException é gerada. Se for feita uma solicitação para image.png, a solicitação será redirecionada para /png-images/image.png. Se for feita uma solicitação para image.jpg, a solicitação será redirecionada para /jpg-images/image.jpg. O código de status é definido como 301 - Moved Permanently, e o context.Result é definido para parar o processamento das regras e enviar a resposta.

public class RedirectImageRequests : IRule
{
    private readonly string _extension;
    private readonly PathString _newPath;

    public RedirectImageRequests(string extension, string newPath)
    {
        if (string.IsNullOrEmpty(extension))
        {
            throw new ArgumentException(nameof(extension));
        }

        if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif)$"))
        {
            throw new ArgumentException("Invalid extension", nameof(extension));
        }

        if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))
        {
            throw new ArgumentException("Invalid path", nameof(newPath));
        }

        _extension = extension;
        _newPath = new PathString(newPath);
    }

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        // Because we're redirecting back to the same app, stop 
        // processing if the request has already been redirected
        if (request.Path.StartsWithSegments(new PathString(_newPath)))
        {
            return;
        }

        if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.HttpContext.Response;
            response.StatusCode = (int) HttpStatusCode.MovedPermanently;
            context.Result = RuleResult.EndResponse;
            response.Headers[HeaderNames.Location] = 
                _newPath + request.Path + request.QueryString;
        }
    }
}

Pedido Original: /image.png

Janela do navegador com ferramentas de desenvolvedor monitorizando as solicitações e respostas de image.png

Pedido Original: /image.jpg

Janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas para image.jpg

Exemplos de Regex

Goal Regex String &
Exemplo de correspondência
String de substituição &
Exemplo de saída
Reescrever caminho em querystring ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Remover barra final (.*)/$
/path/
$1
/path
Impor barra final (.*[^/])$
/path
$1/
/path/
Evite reescrever solicitações específicas ^(.*)(?<!\.axd)$ ou ^(?!.*\.axd$)(.*)$
Sim: /resource.htm
Não: /resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
Reorganizar segmentos de URL path/(.*)/(.*)/(.*)
path/1/2/3
path/$3/$2/$1
path/3/2/1
Substituir um segmento de URL ^(.*)/segment2/(.*)
/segment1/segment2/segment3
$1/replaced/$2
/segment1/replaced/segment3

Este documento apresenta a reconfiguração de URL com instruções sobre como usar o middleware de reconfiguração de URL em aplicativos ASP.NET Core.

A reconfiguração de URL é o ato de modificar URLs de solicitação com base em uma ou mais regras predefinidas. A reescrita de URL cria uma abstração entre os locais dos recursos e os endereços para que os locais e endereços não fiquem estritamente ligados. A reescrita de URLs é valiosa em vários cenários para:

  • Mova ou substitua recursos do servidor temporária ou permanentemente e mantenha localizadores estáveis para esses recursos.
  • Divida o processamento de solicitações entre diferentes aplicativos ou entre áreas de um aplicativo.
  • Remover, adicionar ou reorganizar segmentos de URL em solicitações de entrada.
  • Otimize URLs públicas para Search Engine Optimization (SEO).
  • Permitir o uso de URLs públicas amigáveis para ajudar os visitantes a prever o conteúdo retornado solicitando um recurso.
  • Redirecionar solicitações inseguras para endpoints seguros.
  • Impeça o hotlinking, em que um site externo usa um ativo estático hospedado em outro site vinculando o ativo em seu próprio conteúdo.

Note

A reconfiguração de URL pode reduzir o desempenho de um aplicativo. Sempre que possível, limitar o número e a complexidade das regras.

Visualizar ou descarregar amostra de código (como descarregar)

Redirecionamento de URL e reescrita de URL

A diferença na redação entre redirecionamento de URL e regravação de URL é sutil, mas tem implicações importantes para fornecer recursos aos clientes. O Middleware de Reescrita de URL do ASP.NET Core é capaz de atender à necessidade de ambos.

Um redirecionamento de URL envolve uma operação do lado do cliente, onde o cliente é instruído a acessar um recurso em um endereço diferente do que o cliente solicitou originalmente. Isso requer uma viagem de ida e volta ao servidor. A URL de redirecionamento retornada ao cliente aparece na barra de endereço do navegador quando o cliente faz uma nova solicitação para o recurso.

Se /resource for redirecionado para /different-resource, o servidor responde que o cliente deve obter o recurso em /different-resource com um código de status indicando que o redirecionamento é temporário ou permanente.

Um ponto de extremidade do serviço WebAPI foi temporariamente alterado da versão 1 (v1) para a versão 2 (v2) no servidor. Um cliente faz uma solicitação ao serviço no caminho /v1/api da versão 1. O servidor envia de volta uma resposta 302 (Found) com o novo caminho temporário para o serviço na versão 2 /v2/api. O cliente faz uma segunda solicitação ao serviço na URL de redirecionamento. O servidor responde com um código de status 200 (OK).

Ao redirecionar solicitações para uma URL diferente, indique se o redirecionamento é permanente ou temporário especificando o código de status com a resposta:

  • O 301 - Moved Permanently código de status é usado quando o recurso tem uma URL nova e permanente e você deseja instruir o cliente que todas as solicitações futuras para o recurso devem usar a nova URL. O cliente pode armazenar em cache e reutilizar a resposta quando um código de status 301 é recebido.

  • O código de status 302 - Encontrado é usado quando o redirecionamento é temporário ou geralmente sujeito a alterações. O código de status 302 indica ao cliente para não armazenar a URL nem utilizá-la no futuro.

Para obter mais informações sobre códigos de status, consulte RFC 9110: Definições de código de status.

Uma reescrita de URL é uma operação do lado do servidor que fornece um recurso a partir de um endereço de recurso diferente do que o cliente solicitou. Reescrever uma URL não requer uma viagem de ida e volta ao servidor. O URL reescrito não é devolvido ao cliente e não aparece na barra de endereço do navegador.

Se /resource for reescrito para /different-resource, o servidor busca internamente e retorna o recurso em /different-resource.

Embora o cliente possa recuperar o recurso na URL reescrita, o cliente não é informado de que o recurso existe na URL reescrita quando faz sua solicitação e recebe a resposta.

Um ponto de extremidade do serviço WebAPI foi alterado da versão 1 (v1) para a versão 2 (v2) no servidor. Um cliente faz uma solicitação ao serviço no caminho /v1/api da versão 1. A URL da solicitação é reescrita para acessar o serviço no caminho /v2/api da versão 2. O serviço responde ao cliente com um código de status 200 (OK).

Aplicação de exemplo de reescrita de URL

Você pode explorar os recursos do URL Rewriting Middleware com o aplicativo de exemplo. O aplicativo aplica regras de redirecionamento e reescrita e mostra a URL redirecionada ou reescrita para vários cenários.

Quando usar o middleware de reconfiguração de URL

Use o middleware de reconfiguração de URL quando não conseguir usar as seguintes abordagens:

Além disso, use o middleware quando o aplicativo estiver hospedado em HTTP.sys servidor (anteriormente chamado WebListener).

As principais razões para usar as tecnologias de regravação de URL baseadas em servidor no IIS, Apache e Nginx são:

  • O middleware não suporta todos os recursos desses módulos.

    Alguns dos recursos dos módulos de servidor não funcionam com projetos ASP.NET Core, como as restrições IsFile e IsDirectory do módulo de reescrita do IIS. Nesses cenários, use o middleware em vez disso.

  • O desempenho do middleware provavelmente não corresponde ao dos módulos.

    O benchmarking é a única maneira de saber com certeza qual abordagem degrada mais o desempenho ou se o desempenho degradado é insignificante.

Package

Para incluir o middleware em seu projeto, adicione uma referência de pacote ao metapacote Microsoft.AspNetCore.App no arquivo de projeto, que contém o pacote Microsoft.AspNetCore.Rewrite .

Quando não estiver usando o Microsoft.AspNetCore.App metapacote, adicione uma referência de projeto ao Microsoft.AspNetCore.Rewrite pacote.

Extensão e opções

Estabeleça regras de reescrita e redirecionamento de URL criando uma instância da classe RewriteOptions com métodos de extensão para cada uma das suas regras de reescrita. Encadeie várias regras na ordem em que você gostaria que fossem processadas. Os RewriteOptions são passados para o URL Rewriting Middleware quando é adicionado ao pipeline de solicitação com UseRewriter:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Redirecionar não-www para www

Três opções permitem que o app redirecione solicitações não www para www:

  • AddRedirectToWwwPermanent: Redirecione permanentemente o pedido para o subdomínio www se o pedido não for www. Esta função redireciona com um código de estado Status308PermanentRedirect.

  • AddRedirectToWww: Redirecionar a solicitação para o subdomínio www se a solicitação de entrada não for www. Redireciona com o código de estado Status307TemporaryRedirect. Uma sobrecarga permite que você forneça o código de status para a resposta. Use um campo da StatusCodes classe para uma atribuição de código de status.

Redirecionamento de URL

Use AddRedirect para redirecionar solicitações. O primeiro parâmetro contém seu regex para correspondência no caminho da URL de entrada. O segundo parâmetro é a string de substituição. O terceiro parâmetro, se presente, especifica o código de status. Se você não especificar o código de status, o padrão do código de status será 302 - Encontrado, o que indica que o recurso foi movido ou substituído temporariamente.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Em um navegador com as ferramentas de desenvolvedor habilitadas, faça uma solicitação para o aplicativo de exemplo com o caminho /redirect-rule/1234/5678. O regex corresponde ao caminho da solicitação no redirect-rule/(.*), e o caminho é substituído por /redirected/1234/5678. O URL de redirecionamento é enviado de volta ao cliente com um código de status 302 - Encontrado . O navegador faz uma nova solicitação no URL de redirecionamento, que aparece na barra de endereço do navegador. Como nenhuma regra no aplicativo de exemplo corresponde ao URL de redirecionamento:

  • A segunda solicitação recebe uma resposta 200 - OK do aplicativo.
  • O corpo da resposta mostra o URL de redirecionamento.

Uma viagem de ida e volta é feita para o servidor quando uma URL é redirecionada.

Warning

Seja cauteloso ao estabelecer regras de redirecionamento. As regras de redirecionamento são avaliadas em cada solicitação para o aplicativo, inclusive após um redirecionamento. É fácil criar acidentalmente um loop de redirecionamentos infinitos.

Pedido Original: /redirect-rule/1234/5678

Adicionar redirecionamento: janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas

A parte da expressão contida entre parênteses é chamada de grupo de captura. O ponto (.) da expressão significa corresponder a qualquer caractere. O asterisco (*) indica corresponder ao caractere anterior zero ou mais vezes. Portanto, os dois últimos segmentos de caminho da URL, 1234/5678, são capturados pelo grupo (.*)de captura. Qualquer valor fornecido na URL de solicitação depois redirect-rule/ é capturado por esse único grupo de captura.

Na cadeia de substituição, os grupos capturados são inseridos na cadeia usando o símbolo de cifrão ($) seguido pelo número de sequência da captura. O primeiro valor do grupo de captura é obtido com $1, o segundo com $2, e eles continuam em sequência para os grupos de captura em seu regex. Há apenas um grupo capturado no regex da regra de redirecionamento no aplicativo de exemplo, portanto, há apenas um grupo injetado na cadeia de caracteres de substituição, que é $1. Quando a regra é aplicada, o URL torna-se /redirected/1234/5678.

Redirecionamento de URL para um endpoint seguro

Use AddRedirectToHttps para redirecionar solicitações HTTP para o mesmo host e caminho usando o protocolo HTTPS. Se o código de status não for fornecido, o middleware assume como padrão 302 - Encontrado. Se a porta não for fornecida:

  • O middleware assume como null padrão.
  • O esquema muda para https (protocolo HTTPS) e o cliente acessa o recurso na porta 443.

O exemplo a seguir mostra como definir o código de status como 301 - Moved Permanently e como alterar a porta para 5001.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttps(301, 5001);

    app.UseRewriter(options);
}

Use AddRedirectToHttpsPermanent para redirecionar solicitações inseguras para o mesmo host e caminho com o protocolo HTTPS seguro na porta 443. O middleware define o código de status como 301 - Moved Permanently.

public void Configure(IApplicationBuilder app)
{
    var options = new RewriteOptions()
        .AddRedirectToHttpsPermanent();

    app.UseRewriter(options);
}

Note

Ao redirecionar para um ponto de extremidade seguro sem a necessidade de regras de redirecionamento adicionais, recomendamos o uso do middleware de redirecionamento HTTPS. Para obter mais informações, consulte o tópico Enforce HTTPS .

O aplicativo de exemplo é capaz de demonstrar como usar AddRedirectToHttps ou AddRedirectToHttpsPermanent. Adicione o método de extensão ao RewriteOptions. Faça uma solicitação insegura para o aplicativo em qualquer URL. Ignore o aviso de segurança do navegador de que o certificado autoassinado não é confiável ou crie uma exceção para confiar no certificado.

Pedido original utilizando AddRedirectToHttps(301, 5001): http://localhost:5000/secure

Adicionar redirecionamento para HTTPS: janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas

Pedido original utilizando AddRedirectToHttpsPermanent: http://localhost:5000/secure

Adicionar redirecionamento para HTTPS permanente: janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas

reescrita de URL

Use AddRewrite para criar uma regra para reescrever URLs. O primeiro parâmetro contém o regex para correspondência no caminho de URL de entrada. O segundo parâmetro é a string de substituição. O terceiro parâmetro, skipRemainingRules: {true|false}, indica ao middleware se deve ou não ignorar regras de reescrita adicionais se a regra atual for aplicada.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Pedido Original: /rewrite-rule/1234/5678

Adicionar reescrita: janela do navegador com ferramentas de desenvolvedor rastreando a solicitação e a resposta

O quilate (^) no início da expressão significa que a correspondência começa no início do caminho da URL.

No exemplo anterior com a regra de redirecionamento, redirect-rule/(.*), não há circunflexo (^) no início do regex. Portanto, quaisquer caracteres podem preceder redirect-rule/ no caminho para uma partida bem-sucedida.

Path Match
/redirect-rule/1234/5678 Yes
/my-cool-redirect-rule/1234/5678 Yes
/anotherredirect-rule/1234/5678 Yes

A regra de reescrita, ^rewrite-rule/(\d+)/(\d+), só corresponde aos caminhos se eles começarem com rewrite-rule/. Na tabela a seguir, observe a diferença na correspondência.

Path Match
/rewrite-rule/1234/5678 Yes
/my-cool-rewrite-rule/1234/5678 No
/anotherrewrite-rule/1234/5678 No

Seguindo a ^rewrite-rule/ parte da expressão, há dois grupos de captura, (\d+)/(\d+). O \d significa corresponde a um dígito (número). O sinal de adição (+) significa corresponder a um ou mais dos caracteres anteriores. Portanto, a URL deve conter um número seguido por uma barra frontal seguida por outro número. Esses grupos de captura são injetados na URL reescrita como $1 e $2. A sequência de substituição da regra de reescrita coloca os grupos capturados na sequência de consulta. O caminho solicitado de /rewrite-rule/1234/5678 é reescrito para obter o recurso em /rewritten?var1=1234&var2=5678. Se uma cadeia de caracteres de consulta estiver presente na solicitação original, ela será preservada quando a URL for reescrita.

Não há ida e volta ao servidor para obter o recurso. Se o recurso existir, ele será buscado e retornado ao cliente com um código de status 200 - OK . Como o cliente não é redirecionado, o URL na barra de endereço do navegador não é alterado. Os clientes não conseguem detetar que ocorreu uma operação de reescrita de URL no servidor.

Note

Use skipRemainingRules: true sempre que possível, pois as regras de correspondência são computacionalmente caras e aumentam o tempo de resposta do aplicativo. Para obter a resposta mais rápida do aplicativo:

  • Ordene a reescrita de regras da regra com correspondência mais frequente para a regra com correspondência menos frequente.
  • Ignore o processamento das regras restantes quando ocorrer uma correspondência e nenhum processamento de regra adicional for necessário.

Apache mod_rewrite (módulo de reescrita do Apache)

Aplique as regras do Apache mod_rewrite com AddApacheModRewrite. Verifique se o arquivo de regras é implantado com o aplicativo. Para obter mais informações e exemplos de regras de mod_rewrite, consulte Apache mod_rewrite.

A StreamReader é usado para ler as regras do arquivo de regras ApacheModRewrite.txt :

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

O aplicativo de exemplo redireciona solicitações de /apache-mod-rules-redirect/(.\*) para /redirected?id=$1. O código de status da resposta é 302 - Encontrado.

# Rewrite path with additional sub directory
RewriteRule ^/apache-mod-rules-redirect/(.*) /redirected?id=$1 [L,R=302]

Pedido Original: /apache-mod-rules-redirect/1234

Adicionar mod_redirect do Apache: Janela do browser com ferramentas de desenvolvimento rastreando as solicitações e respostas

O middleware suporta as seguintes variáveis de servidor Apache mod_rewrite:

  • CONN_REMOTE_ADDR
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_FORWARDED
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_USER_AGENT
  • HTTPS
  • IPV6
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_METHOD
  • REQUEST_SCHEME
  • REQUEST_URI
  • SCRIPT_FILENAME
  • SERVER_ADDR
  • SERVER_PORT
  • SERVER_PROTOCOL
  • TIME
  • TIME_DAY
  • TIME_HOUR
  • TIME_MIN
  • TIME_MON
  • TIME_SEC
  • TIME_WDAY
  • TIME_YEAR

Regras do módulo de reconfiguração de URL do IIS

Para usar o mesmo conjunto de regras que se aplica ao Módulo de Reconfiguração de URL do IIS, use AddIISUrlRewrite. Verifique se o arquivo de regras é implantado com o aplicativo. Não direcione o middleware para usar o arquivo web.config do aplicativo durante a execução no Windows Server IIS. Com o IIS, essas regras devem ser armazenadas fora do arquivo de web.config do aplicativo para evitar conflitos com o módulo de regravação do IIS. Para obter mais informações e exemplos de regras do Módulo de Reescrita de URL do IIS, consulte Usando o Módulo de Regravação de URL 2.0 e Referência de Configuração do Módulo de Regravação de URL.

A StreamReader é usado para ler as regras do IISUrlRewrite.xml arquivo de regras:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

O aplicativo de exemplo reescreve solicitações de /iis-rules-rewrite/(.*) para /rewritten?id=$1. A resposta é enviada ao cliente com um código de status 200 - OK .

<rewrite>
  <rules>
    <rule name="Rewrite segment to id querystring" stopProcessing="true">
      <match url="^iis-rules-rewrite/(.*)$" />
      <action type="Rewrite" url="rewritten?id={R:1}" appendQueryString="false"/>
    </rule>
  </rules>
</rewrite>

Pedido Original: /iis-rules-rewrite/1234

Adicionar regravação de URL do IIS: janela do navegador com ferramentas de desenvolvedor rastreando a solicitação e a resposta

Se você tiver um Módulo de Regravação do IIS ativo com regras de nível de servidor configuradas que afetariam seu aplicativo de maneiras indesejáveis, poderá desabilitar o Módulo de Regravação do IIS para um aplicativo. Para obter mais informações, consulte Desabilitando módulos do IIS.

Funcionalidades não suportadas

O middleware lançado com o ASP.NET Core 2.x não suporta os seguintes recursos do Módulo de Regravação de URL do IIS:

  • Regras de saída
  • Variáveis de servidor personalizadas
  • Wildcards
  • LogRewrittenUrl

Variáveis de servidor suportadas

O middleware suporta as seguintes variáveis de servidor do Módulo de Reescrita de URL do IIS:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • HTTP_ACCEPT
  • HTTP_CONNECTION
  • HTTP_COOKIE
  • HTTP_HOST
  • HTTP_REFERER
  • HTTP_URL
  • HTTP_USER_AGENT
  • HTTPS
  • LOCAL_ADDR
  • QUERY_STRING
  • REMOTE_ADDR
  • REMOTE_PORT
  • REQUEST_FILENAME
  • REQUEST_URI

Note

Você também pode obter um IFileProvider via PhysicalFileProvider. Essa abordagem pode fornecer maior flexibilidade para o local de seus arquivos de regras de reescrita. Certifique-se de que seus arquivos de regras de reescrita sejam implantados no servidor no caminho fornecido.

PhysicalFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());

Regra baseada em método

Use Add para implementar sua própria lógica de regra em um método. Add expõe o RewriteContext, que disponibiliza o HttpContext para uso em seu método. O RewriteContext.Result determina como o processamento de pipeline adicional é manipulado. Defina o valor como um dos RuleResult campos descritos na tabela a seguir.

Reescrever resultado de contexto Action
RuleResult.ContinueRules (padrão) Continuar a aplicar regras.
RuleResult.EndResponse Pare de aplicar regras e envie a resposta.
RuleResult.SkipRemainingRules Pare de aplicar regras e envie o contexto para o próximo middleware.
public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

O aplicativo de exemplo demonstra um método que redireciona solicitações para caminhos que terminam com .xml. Se for feita uma solicitação para /file.xml, a solicitação será redirecionada para /xmlfiles/file.xml. O código de status é definido como 301 - Moved Permanently. Quando o navegador faz uma nova solicitação para /xmlfiles/file.xml, o Static File Middleware serve diretamente o arquivo para o cliente a partir da pasta wwwroot/xmlfiles. Para um redirecionamento, defina explicitamente o código de status da resposta. Caso contrário, um código de status 200 - OK será retornado e o redirecionamento não ocorrerá no cliente.

RewriteRules.cs:

public static void RedirectXmlFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    // Because the client is redirecting back to the same app, stop 
    // processing if the request has already been redirected.
    if (request.Path.StartsWithSegments(new PathString("/xmlfiles")))
    {
        return;
    }

    if (request.Path.Value.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
    {
        var response = context.HttpContext.Response;
        response.StatusCode = (int) HttpStatusCode.MovedPermanently;
        context.Result = RuleResult.EndResponse;
        response.Headers[HeaderNames.Location] = 
            "/xmlfiles" + request.Path + request.QueryString;
    }
}

Essa abordagem também pode reescrever solicitações. A aplicação de exemplo demonstra reescrever o caminho para qualquer solicitação de arquivo de texto para servir o ficheiro de texto file.txt a partir da pasta wwwroot. O Middleware de Arquivo Estático serve o arquivo com base no caminho de solicitação atualizado:

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

RewriteRules.cs:

public static void RewriteTextFileRequests(RewriteContext context)
{
    var request = context.HttpContext.Request;

    if (request.Path.Value.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
        context.Result = RuleResult.SkipRemainingRules;
        request.Path = "/file.txt";
    }
}

Regra baseada em IRule

Use Add para usar a lógica de regra em uma classe que implementa a IRule interface. IRule proporciona maior flexibilidade em relação ao uso da abordagem de regra baseada em método. Sua classe de implementação pode incluir um construtor que permite que você possa passar parâmetros para o ApplyRule método.

public void Configure(IApplicationBuilder app)
{
    using (StreamReader apacheModRewriteStreamReader = 
        File.OpenText("ApacheModRewrite.txt"))
    using (StreamReader iisUrlRewriteStreamReader = 
        File.OpenText("IISUrlRewrite.xml")) 
    {
        var options = new RewriteOptions()
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", 
                skipRemainingRules: true)
            .AddApacheModRewrite(apacheModRewriteStreamReader)
            .AddIISUrlRewrite(iisUrlRewriteStreamReader)
            .Add(MethodRules.RedirectXmlFileRequests)
            .Add(MethodRules.RewriteTextFileRequests)
            .Add(new RedirectImageRequests(".png", "/png-images"))
            .Add(new RedirectImageRequests(".jpg", "/jpg-images"));

        app.UseRewriter(options);
    }

    app.UseStaticFiles();

    app.Run(context => context.Response.WriteAsync(
        $"Rewritten or Redirected Url: " +
        $"{context.Request.Path + context.Request.QueryString}"));
}

Os valores dos parâmetros no aplicativo de exemplo para o extension e o newPath são verificados para atender a várias condições. O extension deve conter um valor, e o valor deve ser .png, .jpgou .gif. Se o newPath não for válido, uma ArgumentException é gerada. Se for feita uma solicitação para image.png, a solicitação será redirecionada para /png-images/image.png. Se for feita uma solicitação para image.jpg, a solicitação será redirecionada para /jpg-images/image.jpg. O código de status é definido como 301 - Moved Permanently, e o context.Result é definido para parar o processamento das regras e enviar a resposta.

public class RedirectImageRequests : IRule
{
    private readonly string _extension;
    private readonly PathString _newPath;

    public RedirectImageRequests(string extension, string newPath)
    {
        if (string.IsNullOrEmpty(extension))
        {
            throw new ArgumentException(nameof(extension));
        }

        if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif)$"))
        {
            throw new ArgumentException("Invalid extension", nameof(extension));
        }

        if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))
        {
            throw new ArgumentException("Invalid path", nameof(newPath));
        }

        _extension = extension;
        _newPath = new PathString(newPath);
    }

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        // Because we're redirecting back to the same app, stop 
        // processing if the request has already been redirected
        if (request.Path.StartsWithSegments(new PathString(_newPath)))
        {
            return;
        }

        if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.HttpContext.Response;
            response.StatusCode = (int) HttpStatusCode.MovedPermanently;
            context.Result = RuleResult.EndResponse;
            response.Headers[HeaderNames.Location] = 
                _newPath + request.Path + request.QueryString;
        }
    }
}

Pedido Original: /image.png

Para image.png: Janela do navegador com ferramentas de desenvolvimento monitorizando as solicitações e respostas

Pedido Original: /image.jpg

Para image.jpg: Janela do navegador com ferramentas de desenvolvedor rastreando as solicitações e respostas

Exemplos de Regex

Goal Regex String &
Exemplo de correspondência
String de substituição &
Exemplo de saída
Reescrever caminho em querystring ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Remover barra final (.*)/$
/path/
$1
/path
Impor barra final (.*[^/])$
/path
$1/
/path/
Evite reescrever solicitações específicas ^(.*)(?<!\.axd)$ ou ^(?!.*\.axd$)(.*)$
Sim: /resource.htm
Não: /resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
Reorganizar segmentos de URL path/(.*)/(.*)/(.*)
path/1/2/3
path/$3/$2/$1
path/3/2/1
Substituir um segmento de URL ^(.*)/segment2/(.*)
/segment1/segment2/segment3
$1/replaced/$2
/segment1/replaced/segment3

Recursos adicionais