Middleware de Reconfiguração de URL no ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 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 reconfiguração de URL cria uma abstração entre locais de recursos e seus endereços, de forma que os locais e os endereços não estejam totalmente vinculados. A reconfiguração de URL é útil em vários cenários para:
- Mover ou substituir recursos de servidor temporária ou permanentemente e manter localizadores estáveis para esses recursos.
- Dividir o processamento de solicitação entre diferentes aplicativos ou áreas de um aplicativo.
- Remover, adicionar ou reorganizar segmentos de URL em solicitações de entrada.
- Otimizar URLs públicas para SEO (Otimização do Mecanismo de Pesquisa).
- Permitir o uso de URLs públicas amigáveis para ajudar os visitantes a prever o conteúdo retornado ao solicitar um recurso.
- Redirecionar solicitações não seguras para pontos de extremidade seguros.
- Impedir o hotlink, em que um site externo usa um ativo estático hospedado em outro site vinculando o ativo ao 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 e reconfiguração de URL
A diferença entre os termos redirecionamento de URL e reconfiguração de URL é sutil, mas tem implicações importantes no fornecimento de recursos aos clientes. O Middleware de Reconfiguração de URL do ASP.NET Core pode atender às necessidades de ambos.
Um redirecionamento de URL envolve uma operação do lado do cliente, em que o cliente é instruído a acessar um recurso em um endereço diferente do que ele solicitou originalmente. Isso exige uma viagem de ida e volta para o servidor. A URL de redirecionamento retornada para o cliente é exibida na barra de endereços do navegador quando o cliente faz uma nova solicitação para o recurso.
Se /resource
é 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.
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 código de status
301 - Moved Permanently
é usado quando o recurso tem uma nova URL permanente e todas as solicitações futuras para o recurso devem usar a nova URL. O cliente pode armazenar a resposta em cache e reutilizá-la quando um código de status 301 é recebido.O código de status
302 - Found
é usado quando o redirecionamento é temporário ou está geralmente sujeito a alterações. O código de status 302 indica para o cliente não armazenar a URL e usá-la no futuro.
Para obter mais informações sobre códigos de status, confira RFC 9110: definições de código de status.
Uma reconfiguração de URL é uma operação do servidor que fornece um recurso de um endereço de recurso diferente do que o solicitado pelo cliente. A reconfiguração de uma URL não exige uma viagem de ida e volta para o servidor. A URL reconfigurada não é retornada para o cliente e não é exibida na barra de endereços do navegador.
Se /resource
é reconfigurado como /different-resource
, o servidor efetua fetch internamente e retorna o recurso em /different-resource
.
Embora o cliente possa ter a capacidade de recuperar o recurso na URL reconfigurada, ele não é informado de que o recurso existe na URL reconfigurada ao fazer a solicitação e receber a resposta.
Aplicativo de exemplo de reconfiguração de URL
Explore as funcionalidades do Middleware de Reconfiguração de URL com o aplicativo de exemplo. O aplicativo aplica as regras de redirecionamento e reconfiguração e mostra a URL redirecionada ou reconfigurada para vários cenários.
Quando usar o middleware de reconfiguração de URL
Use o Middleware de Reescrita de URL quando as seguintes abordagens não forem satisfatórias:
- Módulo de Reconfiguração de URL com o IIS no Windows Server
- Módulo mod_rewrite do Apache no Apache Server
- Reconfiguração de URL no Nginx
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 reconfiguração de URL baseada em servidor no IIS, no Apache e no Nginx são:
O middleware não dá suporte às funcionalidades completas desses módulos.
Algumas funcionalidades dos módulos de servidor não funcionam com projetos ASP.NET Core, como as restrições
IsFile
eIsDirectory
do módulo de Reconfiguração do IIS. Nesses cenários, use o middleware.O desempenho do middleware provavelmente não corresponde ao desempenho dos módulos.
Os parâmetros de comparação são a única maneira de saber com certeza qual abordagem degrada mais o desempenho ou se a degradação de desempenho é insignificante.
Extensão e opções
Estabeleça regras de reconfiguração e redirecionamento de URL criando uma instância da classe RewriteOptions com métodos de extensão para cada uma das regras de reconfiguração. Encadear várias regras na ordem em que elas devem ser processadas. As RewriteOptions
são passadas para o Middleware de Reconfiguração de URL, conforme ele é 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. Confira RewriteRules.cs
neste artigo para obter mais informações.
Redirecionar não www para www
Três opções permitem que o aplicativo redirecione solicitações não www
para www
:
AddRedirectToWwwPermanent: redirecionar permanentemente a solicitação para o subdomínio
www
se a solicitação não forwww
. Redireciona com um código de status Status308PermanentRedirect.AddRedirectToWww: redirecionar a solicitação para o subdomínio
www
se a solicitação de entrada não forwww
. Redireciona com um código de status Status307TemporaryRedirect. Uma sobrecarga permite fornecer o código de status para a resposta. Use um campo da classe StatusCodes para uma atribuição de código de status.
Redirecionamento de URL
Use AddRedirect para redirecionar as 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 cadeia de caracteres 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, ele usará como padrão 302 – Encontrado, que indica que o recurso foi substituído ou movido 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 para desenvolvedores 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 de solicitação em redirect-rule/(.*)
e o caminho é substituído por /redirected/1234/5678
. A URL de redirecionamento é enviada novamente ao cliente com um código de status 302 – Encontrado. O navegador faz uma nova solicitação na URL de redirecionamento, que é exibida na barra de endereços do navegador. Como não há nenhuma correspondência de regras no aplicativo de exemplo na URL de redirecionamento:
- A segunda solicitação recebe uma resposta 200 – OK do aplicativo.
- O corpo da resposta mostra a URL de redirecionamento.
Uma viagem de ida e volta é feita para o servidor quando uma URL é redirecionada.
Aviso
Tenha cuidado ao estabelecer regras de redirecionamento. As regras de redirecionamento são avaliadas em cada solicitação para o aplicativo, incluindo após um redirecionamento. É fácil criar acidentalmente um loop de redirecionamentos infinitos.
A parte da expressão contida nos parênteses é chamada um grupo de captura. O ponto (.
) da expressão significa corresponder a qualquer caractere. O asterisco (*
) indica corresponder ao caractere zero precedente 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 após redirect-rule/
é capturado por esse único grupo de captura.
Na cadeia de caracteres de substituição, os grupos capturados são injetados na cadeia de caracteres com o cifrão ($
) seguido do 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 $1
, para que haja apenas um grupo injetado na cadeia de caracteres de substituição, que é redirect-rule/(.*)
. Quando a regra é aplicada, a URL se torna /redirected/1234/5678
.
Experimente /redirect-rule/1234/5678
com as ferramentas do navegador na guia rede.
Redirecionamento de URL para um ponto de extremidade 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 usará como padrão 302 – Encontrado. Se a porta não for fornecida:
- O middleware usará como padrão
null
. - O esquema será alterado para
https
(protocolo HTTPS), e o cliente acessará o recurso na porta 443.
O exemplo a seguir mostra como definir o código de status como 301 - Moved Permanently
e alterar a porta para a porta HTTPS usada pelo Kestrel no localhost. Em produção, a porta HTTPS é definida como nula:
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 não seguras 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();
Observação
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 mais informações, consulte Impor o HTTPS.
O aplicativo de exemplo demonstra como usar AddRedirectToHttps
ou AddRedirectToHttpsPermanent
. Faça uma solicitação HTTP não segura para o aplicativo no 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. A URL HTTP está no arquivo
Properties/launchSettings.json
. - A remoção do
s
dehttps://localhost/{port}
falha porque o localhost não responde no HTTP à porta HTTPS.
A imagem a seguir mostra a imagem das ferramentas do navegador F12 de uma solicitação para http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
usar o código anterior:
Reconfiguração de URL
Use AddRewrite para criar uma regra para a reconfiguração de 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 cadeia de caracteres de substituição. O terceiro parâmetro, skipRemainingRules: {true|false}
, indica para o middleware se ele deve ou não ignorar regras de reconfiguração adicionais se a regra atual é 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 a solicitação para https://redirect6.azurewebsites.net/rewrite-rule/1234/5678
O acento circunflexo (^
) 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á nenhum acento circunflexo (^
) no início da expressão regular. Portanto, qualquer caractere pode preceder redirect-rule/
no caminho para uma correspondência com êxito.
Caminho | Corresponder a |
---|---|
/redirect-rule/1234/5678 |
Sim |
/my-cool-redirect-rule/1234/5678 |
Sim |
/anotherredirect-rule/1234/5678 |
Sim |
A regra de reconfiguração, ^rewrite-rule/(\d+)/(\d+)
, corresponde apenas a caminhos se eles são iniciados com rewrite-rule/
. Na tabela a seguir, observe a diferença na correspondência.
Caminho | Corresponder a |
---|---|
/rewrite-rule/1234/5678 |
Sim |
/my-cool-rewrite-rule/1234/5678 |
Não |
/anotherrewrite-rule/1234/5678 |
Não |
Após a parte ^rewrite-rule/
da expressão, há dois grupos de captura, (\d+)/(\d+)
. O \d
significa corresponder a um dígito (número). O sinal de adição (+
) significa corresponder a um ou mais caracteres anteriores. Portanto, a URL precisa conter um número seguido de uma barra "/" seguida de outro número. Esses grupos de captura são injetados na URL reconfigurada como $1
e $2
. A cadeia de caracteres de substituição da regra de reconfiguração coloca os grupos capturados na cadeia de consulta. O caminho solicitado de /rewrite-rule/1234/5678
foi reescrito para obter o recurso em /rewritten?var1=1234&var2=5678
. Se uma cadeia de consulta estiver presente na solicitação original, ela será preservada quando a URL for reconfigurada.
Não há nenhuma viagem de ida e volta para o servidor para retorno do recurso. Se o recurso existir, ele será buscado e retornado para o cliente com um código de status 200 – OK. Como o cliente não é redirecionado, a URL na barra de endereços do navegador não é alterada. Os clientes não conseguem detectar que uma operação de reconfiguração de URL ocorreu no servidor.
Dicas de desempenho para reescrita e redirecionamento de URL
Para a resposta mais rápida:
- Ordene as regras de reconfiguração da regra com correspondência mais frequente para a regra com correspondência menos frequente.
- Use
skipRemainingRules: true
sempre que possível, porque 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.
Aviso
Um usuário mal-intencionado pode fornecer entrada para RegularExpressions
, causando um ataque de negação de serviço. APIs ASP.NET Core Framework que usam RegularExpressions
passam um tempo limite. Por exemplo, as classes RedirectRule e RewriteRule passam um tempo limite de um segundo.
mod_rewrite do Apache
Aplique as regras do mod_rewrite do Apache com AddApacheModRewrite. Verifique se o arquivo de regras foi implantado com o aplicativo. Para obter mais informações e exemplos de regras de mod_rewrite, consulte mod_rewrite do Apache.
Um 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 a solicitação para https://redirect6.azurewebsites.net/apache-mod-rules-redirect/1234
O middleware do Apache dá suporte às seguintes variáveis de servidor do mod_rewrite do Apache:
- 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 foi implantado com o aplicativo. Não instrua o middleware a usar o arquivo web.config do aplicativo quando ele estiver em execução no IIS do Windows Server. Com o IIS, essas regras devem ser armazenadas fora do arquivo web.config do aplicativo para evitar conflitos com o módulo de Reconfiguração do IIS. Para obter mais informações e exemplos de regras do Módulo de Reconfiguração de URL do IIS, consulte Usando o Módulo de Reconfiguração de URL 2.0 e Referência de configuração do Módulo de Reconfiguração de URL.
Um StreamReader é usado para ler as regras do arquivo de regras IISUrlRewrite.xml
:
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 reconfigura as 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 a solicitação para https://redirect6.azurewebsites.net/iis-rules-rewrite/xyz
Aplicativos que têm um Módulo de Reescrita do IIS ativo com regras de nível de servidor configuradas que afetam o aplicativo de maneiras indesejáveis:
- Considere desabilitar o Módulo de Reescrita do IIS para o aplicativo.
- Para obter mais informações, consulte Desabilitando módulos do IIS.
Recursos sem suporte
O middleware não dá suporte aos seguintes recursos do Módulo de Reconfiguração de URL do IIS:
- Regras de saída
- Variáveis de servidor personalizadas
- Curingas
- LogRewrittenUrl
Variáveis de servidor compatíveis
O middleware dá suporte às seguintes variáveis de servidor do Módulo de Reconfiguração 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
IFileProvider pode ser obtido por meio de uma PhysicalFileProvider. Essa abordagem pode fornecer maior flexibilidade para o local dos arquivos de regras de reconfiguração. Verifique se os arquivos de regras de reconfiguração são 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 nos métodos de redirecionamento. A propriedade RewriteContext.Result determina como o processamento de pipeline adicional é manipulado. Defina o valor como um dos campos RuleResult descritos na tabela a seguir.
Resultado do contexto de reescrita | Ação |
---|---|
RuleResult.ContinueRules (padrão) |
Continuar aplicando regras. |
RuleResult.EndResponse |
Parar de aplicar regras e enviar a resposta. |
RuleResult.SkipRemainingRules |
Parar de aplicar regras e enviar 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 as solicitações para caminhos que terminam com .xml
. Quando uma solicitação é feita para /file.xml
:
- A solicitação é redirecionada para
/xmlfiles/file.xml
- O código status é definido como
301 - Moved Permanently
. Quando o navegador faz uma nova solicitação para/xmlfiles/file.xml
, o Middleware de Arquivo Estático fornece o arquivo para o cliente por meio 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 reconfigurar as solicitações. O aplicativo de exemplo demonstra a reconfiguração do caminho de qualquer solicitação de arquivo de texto para fornecer o arquivo de texto file.txt por meio da pasta wwwroot. O Middleware de Arquivo Estático fornece 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 interface IRule. IRule
fornece maior flexibilidade em comparaçã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 método ApplyRule.
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 a extension
e o newPath
são verificados para atender a várias condições. A extension
precisa conter um valor que precisa ser .png
, .jpg
ou .gif
. Se o newPath
não é válido, uma ArgumentException é gerada. Se uma solicitação for feita para image.png
, ela será redirecionada para /png-images/image.png
. Se uma solicitação for feita para image.jpg
, ela será redirecionada para /jpg-images/image.jpg
. O código de status é definido como 301 - Moved Permanently
e o context.Result
é definida para parar o processamento de 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;
}
}
}
Experimente:
- Solicitação PNG:
https://redirect6.azurewebsites.net/image.png
- Solicitação JPG:
https://redirect6.azurewebsites.net/image.jpg
Exemplos do regex
Goal | Cadeia de caracteres do regex & Exemplo de correspondência |
Cadeia de caracteres de substituição & Exemplo de saída |
---|---|---|
Reconfigurar o caminho na cadeia de consulta | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Barra "/" à direita da faixa | ^path2/(.*)/$ /path2/xyz/ |
$1 /path2/xyz |
Impor barra "/" à direita | ^path3/(.*[^/])$ /path3/xyz |
$1/ /path3/xyz/ |
Evitar a reconfiguração de 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 fazer regras de reescrita testáveis exclusivas para o exemplo implantado. Normalmente, a expressão regular não incluiria path
. Por exemplo, confira estas tabelas de exemplos de expressão regular .
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 reconfiguração de URL cria uma abstração entre locais de recursos e seus endereços, de forma que os locais e os endereços não estejam totalmente vinculados. A reconfiguração de URL é útil em vários cenários para:
- Mover ou substituir recursos de servidor temporária ou permanentemente e manter localizadores estáveis para esses recursos.
- Dividir o processamento de solicitação entre diferentes aplicativos ou áreas de um aplicativo.
- Remover, adicionar ou reorganizar segmentos de URL em solicitações de entrada.
- Otimizar URLs públicas para SEO (Otimização do Mecanismo de Pesquisa).
- Permitir o uso de URLs públicas amigáveis para ajudar os visitantes a prever o conteúdo retornado ao solicitar um recurso.
- Redirecionar solicitações não seguras para pontos de extremidade seguros.
- Impedir o hotlink, em que um site externo usa um ativo estático hospedado em outro site vinculando o ativo ao seu próprio conteúdo.
Observação
A reconfiguração de URL pode reduzir o desempenho de um aplicativo. Sempre que possível, limite o número e a complexidade das regras.
Exibir ou baixar código de exemplo (como baixar)
Redirecionamento e reconfiguração de URL
A diferença entre os termos redirecionamento de URL e reconfiguração de URL é sutil, mas tem implicações importantes no fornecimento de recursos aos clientes. O Middleware de Reconfiguração de URL do ASP.NET Core pode atender às necessidades de ambos.
Um redirecionamento de URL envolve uma operação do lado do cliente, em que o cliente é instruído a acessar um recurso em um endereço diferente do que ele solicitou originalmente. Isso exige uma viagem de ida e volta para o servidor. A URL de redirecionamento retornada para o cliente é exibida na barra de endereços do navegador quando o cliente faz uma nova solicitação para o recurso.
Se /resource
é 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.
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 código de status
301 - Moved Permanently
é usado quando o recurso tem uma nova URL 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 a resposta em cache e reutilizá-la quando um código de status 301 é recebido.O código de status 302 – Encontrado é usado quando o redirecionamento é temporário ou está geralmente sujeito a alterações. O código de status 302 indica para o cliente não armazenar a URL e usá-la no futuro.
Para obter mais informações sobre códigos de status, confira RFC 9110: definições de código de status.
Uma reconfiguração de URL é uma operação do servidor que fornece um recurso de um endereço de recurso diferente do que o solicitado pelo cliente. A reconfiguração de uma URL não exige uma viagem de ida e volta para o servidor. A URL reconfigurada não é retornada para o cliente e não é exibida na barra de endereços do navegador.
Se /resource
é reconfigurado como /different-resource
, o servidor efetua fetch internamente e retorna o recurso em /different-resource
.
Embora o cliente possa ter a capacidade de recuperar o recurso na URL reconfigurada, ele não é informado de que o recurso existe na URL reconfigurada ao fazer a solicitação e receber a resposta.
Aplicativo de exemplo de reconfiguração de URL
Explore as funcionalidades do Middleware de Reconfiguração de URL com o aplicativo de exemplo. O aplicativo aplica as regras de redirecionamento e reconfiguração e mostra a URL redirecionada ou reconfigurada 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 for possível usar as seguintes abordagens:
- Módulo de Reconfiguração de URL com o IIS no Windows Server
- Módulo mod_rewrite do Apache no Apache Server
- Reconfiguração de URL no Nginx
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 reconfiguração de URL baseada em servidor no IIS, no Apache e no Nginx são:
O middleware não dá suporte às funcionalidades completas desses módulos.
Algumas funcionalidades dos módulos de servidor não funcionam com projetos ASP.NET Core, como as restrições
IsFile
eIsDirectory
do módulo de Reconfiguração do IIS. Nesses cenários, use o middleware.O desempenho do middleware provavelmente não corresponde ao desempenho dos módulos.
Os parâmetros de comparação são a única maneira de saber com certeza qual abordagem degrada mais o desempenho ou se a degradação de desempenho é insignificante.
Pacote
O Middleware de Reconfiguração de URL é fornecido pelo pacote Microsoft.AspNetCore.Rewrite, que é incluído implicitamente em aplicativos ASP.NET Core.
Extensão e opções
Estabeleça regras de reconfiguração e redirecionamento de URL criando uma instância da classe RewriteOptions com métodos de extensão para cada uma das regras de reconfiguração. Encadeie várias regras na ordem em que deseja que sejam processadas. As RewriteOptions
são passadas para o Middleware de Reconfiguração de URL, conforme ele é 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 aplicativo redirecione solicitações não www
para www
:
AddRedirectToWwwPermanent: redirecionar permanentemente a solicitação para o subdomínio
www
se a solicitação não forwww
. Redireciona com um código de status Status308PermanentRedirect.AddRedirectToWww: redirecionar a solicitação para o subdomínio
www
se a solicitação de entrada não forwww
. Redireciona com um código de status Status307TemporaryRedirect. Uma sobrecarga permite que você forneça o código de status para a resposta. Use um campo da classe StatusCodes para uma atribuição de código de status.
Redirecionamento de URL
Use AddRedirect para redirecionar as solicitações. O primeiro parâmetro contém o Regex para correspondência no caminho da URL de entrada. O segundo parâmetro é a cadeia de caracteres 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, ele usará como padrão 302 – Encontrado, que indica que o recurso foi substituído ou movido 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 para desenvolvedores habilitadas, faça uma solicitação para o aplicativo de exemplo com o caminho /redirect-rule/1234/5678
. O regex corresponde ao caminho de solicitação em redirect-rule/(.*)
e o caminho é substituído por /redirected/1234/5678
. A URL de redirecionamento é enviada novamente ao cliente com um código de status 302 – Encontrado. O navegador faz uma nova solicitação na URL de redirecionamento, que é exibida na barra de endereços do navegador. Como não há nenhuma correspondência de regras no aplicativo de exemplo na URL de redirecionamento:
- A segunda solicitação recebe uma resposta 200 – OK do aplicativo.
- O corpo da resposta mostra a URL de redirecionamento.
Uma viagem de ida e volta é feita para o servidor quando uma URL é redirecionada.
Aviso
Tenha cuidado ao estabelecer regras de redirecionamento. As regras de redirecionamento são avaliadas em cada solicitação para o aplicativo, incluindo após um redirecionamento. É fácil criar acidentalmente um loop de redirecionamentos infinitos.
Solicitação original: /redirect-rule/1234/5678
A parte da expressão contida nos parênteses é chamada um grupo de captura. O ponto (.
) da expressão significa corresponder a qualquer caractere. O asterisco (*
) indica corresponder ao caractere zero precedente ou mais vezes. Portanto, os dois últimos segmentos de caminho da URL, 1234/5678
, são capturados pelo grupo de captura (.*)
. Qualquer valor que você fornecer na URL de solicitação após redirect-rule/
é capturado por esse único grupo de captura.
Na cadeia de caracteres de substituição, os grupos capturados são injetados na cadeia de caracteres com o cifrão ($
) seguido do número de sequência da captura. O primeiro valor de grupo de captura é obtido com $1
, o segundo com $2
e eles continuam em sequência para os grupos de captura no regex. Há apenas um grupo capturado no regex da regra de redirecionamento no aplicativo de exemplo, para que haja apenas um grupo injetado na cadeia de caracteres de substituição, que é $1
. Quando a regra é aplicada, a URL se torna /redirected/1234/5678
.
Redirecionamento de URL para um ponto de extremidade 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 usará como padrão 302 – Encontrado. Se a porta não for fornecida:
- O middleware usará como padrão
null
. - O esquema será alterado para
https
(protocolo HTTPS), e o cliente acessará o recurso na porta 443.
O exemplo a seguir mostra como definir o código de status como 301 - Moved Permanently
e 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 não seguras 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);
}
Observação
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, veja o tópico Impor HTTPS.
O aplicativo de exemplo pode demonstrar como usar AddRedirectToHttps
ou AddRedirectToHttpsPermanent
. Adicione o método de extensão às RewriteOptions
. Faça uma solicitação não segura 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.
Solicitação original usando AddRedirectToHttps(301, 5001)
: http://localhost:5000/secure
Solicitação original usando AddRedirectToHttpsPermanent
: http://localhost:5000/secure
Reconfiguração de URL
Use AddRewrite para criar uma regra para a reconfiguração de URLs. O primeiro parâmetro contém o regex para correspondência no caminho da URL de entrada. O segundo parâmetro é a cadeia de caracteres de substituição. O terceiro parâmetro, skipRemainingRules: {true|false}
, indica para o middleware se ele deve ou não ignorar regras de reconfiguração adicionais se a regra atual é 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}"));
}
Solicitação original: /rewrite-rule/1234/5678
O acento circunflexo (^
) 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á nenhum acento circunflexo (^
) no início do regex. Portanto, qualquer caractere pode preceder redirect-rule/
no caminho para uma correspondência com êxito.
Caminho | Corresponder a |
---|---|
/redirect-rule/1234/5678 |
Sim |
/my-cool-redirect-rule/1234/5678 |
Sim |
/anotherredirect-rule/1234/5678 |
Sim |
A regra de reconfiguração, ^rewrite-rule/(\d+)/(\d+)
, corresponde apenas a caminhos se eles são iniciados com rewrite-rule/
. Na tabela a seguir, observe a diferença na correspondência.
Caminho | Corresponder a |
---|---|
/rewrite-rule/1234/5678 |
Sim |
/my-cool-rewrite-rule/1234/5678 |
Não |
/anotherrewrite-rule/1234/5678 |
Não |
Após a parte ^rewrite-rule/
da expressão, há dois grupos de captura, (\d+)/(\d+)
. O \d
significa corresponder a um dígito (número). O sinal de adição (+
) significa corresponder a um ou mais caracteres anteriores. Portanto, a URL precisa conter um número seguido de uma barra "/" seguida de outro número. Esses grupos de captura são injetados na URL reconfigurada como $1
e $2
. A cadeia de caracteres de substituição da regra de reconfiguração coloca os grupos capturados na cadeia de consulta. O caminho solicitado de /rewrite-rule/1234/5678
foi reconfigurado para obter o recurso em /rewritten?var1=1234&var2=5678
. Se uma cadeia de consulta estiver presente na solicitação original, ela será preservada quando a URL for reconfigurada.
Não há nenhuma viagem de ida e volta para o servidor para obtenção do recurso. Se o recurso existir, ele será buscado e retornado para o cliente com um código de status 200 – OK. Como o cliente não é redirecionado, a URL na barra de endereços do navegador não é alterada. Os clientes não conseguem detectar que uma operação de reconfiguração de URL ocorreu no servidor.
Observação
Use skipRemainingRules: true
sempre que possível, porque as regras de correspondência são computacionalmente caras e aumentam o tempo de resposta do aplicativo. Para a resposta mais rápida do aplicativo:
- Ordene as regras de reconfiguração 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.
mod_rewrite do Apache
Aplique as regras do mod_rewrite do Apache com AddApacheModRewrite. Verifique se o arquivo de regras foi implantado com o aplicativo. Para obter mais informações e exemplos de regras de mod_rewrite, consulte mod_rewrite do Apache.
Um 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]
Solicitação original: /apache-mod-rules-redirect/1234
O middleware dá suporte às seguintes variáveis de servidor do mod_rewrite do Apache:
- 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 foi implantado com o aplicativo. Não instrua o middleware a usar o arquivo web.config do aplicativo quando ele estiver em execução no IIS do Windows Server. Com o IIS, essas regras devem ser armazenadas fora do arquivo web.config do aplicativo para evitar conflitos com o módulo de Reconfiguração do IIS. Para obter mais informações e exemplos de regras do Módulo de Reconfiguração de URL do IIS, consulte Usando o Módulo de Reconfiguração de URL 2.0 e Referência de configuração do Módulo de Reconfiguração de URL.
Um StreamReader é usado para ler as regras do arquivo de regras IISUrlRewrite.xml
:
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 reconfigura as 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>
Solicitação original: /iis-rules-rewrite/1234
Caso você tenha um Módulo de Reconfiguração do IIS ativo com regras no nível do servidor configuradas que poderiam afetar o aplicativo de maneiras indesejadas, desabilite o Módulo de Reconfiguração do IIS em um aplicativo. Para obter mais informações, consulte Desabilitando módulos do IIS.
Recursos sem suporte
O middleware não dá suporte aos seguintes recursos do Módulo de Reconfiguração de URL do IIS:
- Regras de saída
- Variáveis de servidor personalizadas
- Curingas
- LogRewrittenUrl
Variáveis de servidor compatíveis
O middleware dá suporte às seguintes variáveis de servidor do Módulo de Reconfiguração 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
Observação
Também obtenha um IFileProvider por meio de um PhysicalFileProvider. Essa abordagem pode fornecer maior flexibilidade para o local dos arquivos de regras de reconfiguração. Verifique se os arquivos de regras de reconfiguração são 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 no método. O RewriteContext.Result determina como o processamento adicional de pipeline é feito. Defina o valor como um dos campos RuleResult descritos na tabela a seguir.
Resultado do contexto de reescrita | Ação |
---|---|
RuleResult.ContinueRules (padrão) |
Continuar aplicando regras. |
RuleResult.EndResponse |
Parar de aplicar regras e enviar a resposta. |
RuleResult.SkipRemainingRules |
Parar de aplicar regras e enviar 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 as solicitações para caminhos que terminam com .xml
. Se uma solicitação for feita para /file.xml
, ela será redirecionada para /xmlfiles/file.xml
. O código status é definido como 301 - Moved Permanently
. Quando o navegador faz uma nova solicitação para /xmlfiles/file.xml
, o Middleware de Arquivo Estático fornece o arquivo para o cliente por meio 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 reconfigurar as solicitações. O aplicativo de exemplo demonstra a reconfiguração do caminho de qualquer solicitação de arquivo de texto para fornecer o arquivo de texto file.txt por meio da pasta wwwroot. O Middleware de Arquivo Estático fornece 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 interface IRule. IRule
fornece maior flexibilidade em comparaçã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 método ApplyRule.
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 a extension
e o newPath
são verificados para atender a várias condições. A extension
precisa conter um valor que precisa ser .png
, .jpg
ou .gif. Se o newPath
não é válido, uma ArgumentException é gerada. Se uma solicitação for feita para image.png
, ela será redirecionada para /png-images/image.png
. Se uma solicitação for feita para image.jpg
, ela será redirecionada para /jpg-images/image.jpg
. O código de status é definido como 301 - Moved Permanently
e o context.Result
é definida para parar o processamento de 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;
}
}
}
Solicitação original: /image.png
Solicitação original: /image.jpg
Exemplos do regex
Goal | Cadeia de caracteres do regex & Exemplo de correspondência |
Cadeia de caracteres de substituição & Exemplo de saída |
---|---|---|
Reconfigurar o caminho na cadeia de consulta | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Barra "/" à direita da faixa | (.*)/$ /path/ |
$1 /path |
Impor barra "/" à direita | (.*[^/])$ /path |
$1/ /path/ |
Evitar a reconfiguração de 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 reconfiguração de URL cria uma abstração entre locais de recursos e seus endereços, de forma que os locais e os endereços não estejam totalmente vinculados. A reconfiguração de URL é útil em vários cenários para:
- Mover ou substituir recursos de servidor temporária ou permanentemente e manter localizadores estáveis para esses recursos.
- Dividir o processamento de solicitação entre diferentes aplicativos ou áreas de um aplicativo.
- Remover, adicionar ou reorganizar segmentos de URL em solicitações de entrada.
- Otimizar URLs públicas para SEO (Otimização do Mecanismo de Pesquisa).
- Permitir o uso de URLs públicas amigáveis para ajudar os visitantes a prever o conteúdo retornado ao solicitar um recurso.
- Redirecionar solicitações não seguras para pontos de extremidade seguros.
- Impedir o hotlink, em que um site externo usa um ativo estático hospedado em outro site vinculando o ativo ao seu próprio conteúdo.
Observação
A reconfiguração de URL pode reduzir o desempenho de um aplicativo. Sempre que possível, limite o número e a complexidade das regras.
Exibir ou baixar código de exemplo (como baixar)
Redirecionamento e reconfiguração de URL
A diferença entre os termos redirecionamento de URL e reconfiguração de URL é sutil, mas tem implicações importantes no fornecimento de recursos aos clientes. O Middleware de Reconfiguração de URL do ASP.NET Core pode atender às necessidades de ambos.
Um redirecionamento de URL envolve uma operação do lado do cliente, em que o cliente é instruído a acessar um recurso em um endereço diferente do que ele solicitou originalmente. Isso exige uma viagem de ida e volta para o servidor. A URL de redirecionamento retornada para o cliente é exibida na barra de endereços do navegador quando o cliente faz uma nova solicitação para o recurso.
Se /resource
é 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.
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 código de status
301 - Moved Permanently
é usado quando o recurso tem uma nova URL 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 a resposta em cache e reutilizá-la quando um código de status 301 é recebido.O código de status 302 – Encontrado é usado quando o redirecionamento é temporário ou está geralmente sujeito a alterações. O código de status 302 indica para o cliente não armazenar a URL e usá-la no futuro.
Para obter mais informações sobre códigos de status, confira RFC 9110: definições de código de status.
Uma reconfiguração de URL é uma operação do servidor que fornece um recurso de um endereço de recurso diferente do que o solicitado pelo cliente. A reconfiguração de uma URL não exige uma viagem de ida e volta para o servidor. A URL reconfigurada não é retornada para o cliente e não é exibida na barra de endereços do navegador.
Se /resource
é reconfigurado como /different-resource
, o servidor efetua fetch internamente e retorna o recurso em /different-resource
.
Embora o cliente possa ter a capacidade de recuperar o recurso na URL reconfigurada, ele não é informado de que o recurso existe na URL reconfigurada ao fazer a solicitação e receber a resposta.
Aplicativo de exemplo de reconfiguração de URL
Explore as funcionalidades do Middleware de Reconfiguração de URL com o aplicativo de exemplo. O aplicativo aplica as regras de redirecionamento e reconfiguração e mostra a URL redirecionada ou reconfigurada 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 for possível usar as seguintes abordagens:
- Módulo de Reconfiguração de URL com o IIS no Windows Server
- Módulo mod_rewrite do Apache no Apache Server
- Reconfiguração de URL no Nginx
Além disso, use o middleware quando o aplicativo estiver hospedado no servidor HTTP.sys (anteriormente chamado WebListener).
As principais razões para usar as tecnologias de reconfiguração de URL baseada em servidor no IIS, no Apache e no Nginx são:
O middleware não dá suporte às funcionalidades completas desses módulos.
Algumas funcionalidades dos módulos de servidor não funcionam com projetos ASP.NET Core, como as restrições
IsFile
eIsDirectory
do módulo de Reconfiguração do IIS. Nesses cenários, use o middleware.O desempenho do middleware provavelmente não corresponde ao desempenho dos módulos.
Os parâmetros de comparação são a única maneira de saber com certeza qual abordagem degrada mais o desempenho ou se a degradação de desempenho é insignificante.
Pacote
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 metapacote Microsoft.AspNetCore.App
, adicione uma referência de projeto ao pacote Microsoft.AspNetCore.Rewrite
.
Extensão e opções
Estabeleça regras de reconfiguração e redirecionamento de URL criando uma instância da classe RewriteOptions com métodos de extensão para cada uma das regras de reconfiguração. Encadeie várias regras na ordem em que deseja que sejam processadas. As RewriteOptions
são passadas para o Middleware de Reconfiguração de URL, conforme ele é 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 aplicativo redirecione solicitações não www
para www
:
AddRedirectToWwwPermanent: redirecionar permanentemente a solicitação para o subdomínio
www
se a solicitação não forwww
. Redireciona com um código de status Status308PermanentRedirect.AddRedirectToWww: redirecionar a solicitação para o subdomínio
www
se a solicitação de entrada não forwww
. Redireciona com um código de status Status307TemporaryRedirect. Uma sobrecarga permite que você forneça o código de status para a resposta. Use um campo da classe StatusCodes para uma atribuição de código de status.
Redirecionamento de URL
Use AddRedirect para redirecionar as solicitações. O primeiro parâmetro contém o regex para correspondência no caminho da URL de entrada. O segundo parâmetro é a cadeia de caracteres 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, ele usará como padrão 302 – Encontrado, que indica que o recurso foi substituído ou movido 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 para desenvolvedores habilitadas, faça uma solicitação para o aplicativo de exemplo com o caminho /redirect-rule/1234/5678
. O regex corresponde ao caminho de solicitação em redirect-rule/(.*)
e o caminho é substituído por /redirected/1234/5678
. A URL de redirecionamento é enviada novamente ao cliente com um código de status 302 – Encontrado. O navegador faz uma nova solicitação na URL de redirecionamento, que é exibida na barra de endereços do navegador. Como não há nenhuma correspondência de regras no aplicativo de exemplo na URL de redirecionamento:
- A segunda solicitação recebe uma resposta 200 – OK do aplicativo.
- O corpo da resposta mostra a URL de redirecionamento.
Uma viagem de ida e volta é feita para o servidor quando uma URL é redirecionada.
Aviso
Tenha cuidado ao estabelecer regras de redirecionamento. As regras de redirecionamento são avaliadas em cada solicitação para o aplicativo, incluindo após um redirecionamento. É fácil criar acidentalmente um loop de redirecionamentos infinitos.
Solicitação original: /redirect-rule/1234/5678
A parte da expressão contida nos parênteses é chamada um grupo de captura. O ponto (.
) da expressão significa corresponder a qualquer caractere. O asterisco (*
) indica corresponder ao caractere zero precedente ou mais vezes. Portanto, os dois últimos segmentos de caminho da URL, 1234/5678
, são capturados pelo grupo de captura (.*)
. Qualquer valor que você fornecer na URL de solicitação após redirect-rule/
é capturado por esse único grupo de captura.
Na cadeia de caracteres de substituição, os grupos capturados são injetados na cadeia de caracteres com o cifrão ($
) seguido do número de sequência da captura. O primeiro valor de grupo de captura é obtido com $1
, o segundo com $2
e eles continuam em sequência para os grupos de captura no regex. Há apenas um grupo capturado no regex da regra de redirecionamento no aplicativo de exemplo, para que haja apenas um grupo injetado na cadeia de caracteres de substituição, que é $1
. Quando a regra é aplicada, a URL se torna /redirected/1234/5678
.
Redirecionamento de URL para um ponto de extremidade 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 usará como padrão 302 – Encontrado. Se a porta não for fornecida:
- O middleware usará como padrão
null
. - O esquema será alterado para
https
(protocolo HTTPS), e o cliente acessará o recurso na porta 443.
O exemplo a seguir mostra como definir o código de status como 301 - Moved Permanently
e 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 não seguras 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);
}
Observação
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, veja o tópico Impor HTTPS.
O aplicativo de exemplo pode demonstrar como usar AddRedirectToHttps
ou AddRedirectToHttpsPermanent
. Adicione o método de extensão às RewriteOptions
. Faça uma solicitação não segura 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.
Solicitação original usando AddRedirectToHttps(301, 5001)
: http://localhost:5000/secure
Solicitação original usando AddRedirectToHttpsPermanent
: http://localhost:5000/secure
Reconfiguração de URL
Use AddRewrite para criar uma regra para a reconfiguração de URLs. O primeiro parâmetro contém o regex para correspondência no caminho da URL de entrada. O segundo parâmetro é a cadeia de caracteres de substituição. O terceiro parâmetro, skipRemainingRules: {true|false}
, indica para o middleware se ele deve ou não ignorar regras de reconfiguração adicionais se a regra atual é 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}"));
}
Solicitação original: /rewrite-rule/1234/5678
O acento circunflexo (^
) 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á nenhum acento circunflexo (^
) no início do regex. Portanto, qualquer caractere pode preceder redirect-rule/
no caminho para uma correspondência com êxito.
Caminho | Corresponder a |
---|---|
/redirect-rule/1234/5678 |
Sim |
/my-cool-redirect-rule/1234/5678 |
Sim |
/anotherredirect-rule/1234/5678 |
Sim |
A regra de reconfiguração, ^rewrite-rule/(\d+)/(\d+)
, corresponde apenas a caminhos se eles são iniciados com rewrite-rule/
. Na tabela a seguir, observe a diferença na correspondência.
Caminho | Corresponder a |
---|---|
/rewrite-rule/1234/5678 |
Sim |
/my-cool-rewrite-rule/1234/5678 |
Não |
/anotherrewrite-rule/1234/5678 |
Não |
Após a parte ^rewrite-rule/
da expressão, há dois grupos de captura, (\d+)/(\d+)
. O \d
significa corresponder a um dígito (número). O sinal de adição (+
) significa corresponder a um ou mais caracteres anteriores. Portanto, a URL precisa conter um número seguido de uma barra "/" seguida de outro número. Esses grupos de captura são injetados na URL reconfigurada como $1
e $2
. A cadeia de caracteres de substituição da regra de reconfiguração coloca os grupos capturados na cadeia de consulta. O caminho solicitado de /rewrite-rule/1234/5678
foi reconfigurado para obter o recurso em /rewritten?var1=1234&var2=5678
. Se uma cadeia de consulta estiver presente na solicitação original, ela será preservada quando a URL for reconfigurada.
Não há nenhuma viagem de ida e volta para o servidor para obtenção do recurso. Se o recurso existir, ele será buscado e retornado para o cliente com um código de status 200 – OK. Como o cliente não é redirecionado, a URL na barra de endereços do navegador não é alterada. Os clientes não conseguem detectar que uma operação de reconfiguração de URL ocorreu no servidor.
Observação
Use skipRemainingRules: true
sempre que possível, porque as regras de correspondência são computacionalmente caras e aumentam o tempo de resposta do aplicativo. Para a resposta mais rápida do aplicativo:
- Ordene as regras de reconfiguração 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.
mod_rewrite do Apache
Aplique as regras do mod_rewrite do Apache com AddApacheModRewrite. Verifique se o arquivo de regras foi implantado com o aplicativo. Para obter mais informações e exemplos de regras de mod_rewrite, consulte mod_rewrite do Apache.
Um 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]
Solicitação original: /apache-mod-rules-redirect/1234
O middleware dá suporte às seguintes variáveis de servidor do mod_rewrite do Apache:
- 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 foi implantado com o aplicativo. Não instrua o middleware a usar o arquivo web.config do aplicativo quando ele estiver em execução no IIS do Windows Server. Com o IIS, essas regras devem ser armazenadas fora do arquivo web.config do aplicativo para evitar conflitos com o módulo de Reconfiguração do IIS. Para obter mais informações e exemplos de regras do Módulo de Reconfiguração de URL do IIS, consulte Usando o Módulo de Reconfiguração de URL 2.0 e Referência de configuração do Módulo de Reconfiguração de URL.
Um StreamReader é usado para ler as regras do arquivo de regras IISUrlRewrite.xml
:
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 reconfigura as 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>
Solicitação original: /iis-rules-rewrite/1234
Caso você tenha um Módulo de Reconfiguração do IIS ativo com regras no nível do servidor configuradas que poderiam afetar o aplicativo de maneiras indesejadas, desabilite o Módulo de Reconfiguração do IIS em um aplicativo. Para obter mais informações, consulte Desabilitando módulos do IIS.
Recursos sem suporte
O middleware liberado com o ASP.NET Core 2.x não dá suporte aos seguintes recursos do Módulo de Reconfiguração de URL do IIS:
- Regras de saída
- Variáveis de servidor personalizadas
- Curingas
- LogRewrittenUrl
Variáveis de servidor compatíveis
O middleware dá suporte às seguintes variáveis de servidor do Módulo de Reconfiguração 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
Observação
Também obtenha um IFileProvider por meio de um PhysicalFileProvider. Essa abordagem pode fornecer maior flexibilidade para o local dos arquivos de regras de reconfiguração. Verifique se os arquivos de regras de reconfiguração são 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 no método. O RewriteContext.Result determina como o processamento adicional de pipeline é feito. Defina o valor como um dos campos RuleResult descritos na tabela a seguir.
Resultado do contexto de reescrita | Ação |
---|---|
RuleResult.ContinueRules (padrão) |
Continuar aplicando regras. |
RuleResult.EndResponse |
Parar de aplicar regras e enviar a resposta. |
RuleResult.SkipRemainingRules |
Parar de aplicar regras e enviar 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 as solicitações para caminhos que terminam com .xml
. Se uma solicitação for feita para /file.xml
, ela será redirecionada para /xmlfiles/file.xml
. O código status é definido como 301 - Moved Permanently
. Quando o navegador faz uma nova solicitação para /xmlfiles/file.xml
, o Middleware de Arquivo Estático fornece o arquivo para o cliente por meio 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 reconfigurar as solicitações. O aplicativo de exemplo demonstra a reconfiguração do caminho de qualquer solicitação de arquivo de texto para fornecer o arquivo de texto file.txt por meio da pasta wwwroot. O Middleware de Arquivo Estático fornece 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 interface IRule. IRule
fornece maior flexibilidade em comparaçã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 método ApplyRule.
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 a extension
e o newPath
são verificados para atender a várias condições. A extension
precisa conter um valor que precisa ser .png
, .jpg
ou .gif. Se o newPath
não é válido, uma ArgumentException é gerada. Se uma solicitação for feita para image.png
, ela será redirecionada para /png-images/image.png
. Se uma solicitação for feita para image.jpg
, ela será redirecionada para /jpg-images/image.jpg
. O código de status é definido como 301 - Moved Permanently
e o context.Result
é definida para parar o processamento de 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;
}
}
}
Solicitação original: /image.png
Solicitação original: /image.jpg
Exemplos do regex
Goal | Cadeia de caracteres do regex & Exemplo de correspondência |
Cadeia de caracteres de substituição & Exemplo de saída |
---|---|---|
Reconfigurar o caminho na cadeia de consulta | ^path/(.*)/(.*) /path/abc/123 |
path?var1=$1&var2=$2 /path?var1=abc&var2=123 |
Barra "/" à direita da faixa | (.*)/$ /path/ |
$1 /path |
Impor barra "/" à direita | (.*[^/])$ /path |
$1/ /path/ |
Evitar a reconfiguração de 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
- Exibir ou baixar código de exemplo (como baixar)
- Fonte RewriteMiddleware no GitHub
- Inicialização de aplicativo no ASP.NET Core
- Middleware do ASP.NET Core
- Expressões regulares no .NET
- Linguagem de expressão regular – referência rápida
- mod_rewrite do Apache
- Usando o Módulo de Reconfiguração de URL 2.0 (para IIS)
- Referência de configuração do Módulo de Reconfiguração de URL
- Manter uma estrutura de URL simples
- 10 dicas e truques de reconfiguração de URL
- Inserir ou não inserir uma barra "/"