Sdílet prostřednictvím


Middleware pro přepis adres URL v ASP.NET Core

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Kirk Larkin a Rick Anderson

Tento článek představuje přepis adres URL s pokyny k použití middlewaru pro přepis adres URL v aplikacích ASP.NET Core.

Přepsání adresy URL je úprava adres URL požadavků na základě jednoho nebo více předdefinovaných pravidel. Přepsání adresy URL vytvoří abstrakci mezi umístěními prostředků a jejich adresami, takže umístění a adresy nejsou úzce propojené. Přepsání adresy URL je cenné v několika scénářích pro:

  • Přesuňte nebo nahraďte prostředky serveru dočasně nebo trvale a udržujte stabilní lokátory těchto prostředků.
  • Rozdělte zpracování žádostí mezi různé aplikace nebo napříč oblastmi jedné aplikace.
  • Odeberte, přidejte nebo reorganizujte segmenty adres URL u příchozích požadavků.
  • Optimalizace veřejných adres URL pro optimalizaci vyhledávacích webů (SEO).
  • Povolte použití přátelských veřejných adres URL, které návštěvníkům pomůžou předpovědět obsah vrácený žádostí o prostředek.
  • Přesměrujte nezabezpečené požadavky na zabezpečené koncové body.
  • Znemožnit propojení s hotlinkingem, kdy externí web používá hostovaný statický prostředek na jiném webu propojením prostředku s vlastním obsahem.

Přepsání adresy URL může snížit výkon aplikace. Omezte počet a složitost pravidel.

Přesměrování adresy URL a přepsání adresy URL

Rozdíl ve formulaci přesměrování adresy URL a přepsání adresy URL je malý, ale má důležité důsledky pro poskytování prostředků klientům. ASP.NET middlewaru pro přepis adresy URL jádra je schopen splnit potřebu obojího.

Přesměrování adresy URL zahrnuje operaci na straně klienta, kde se klientovi dá pokyn, aby přistupoval k prostředku na jiné adrese než původně požadovaný klient. To vyžaduje odezvu na server. Adresa URL přesměrování vrácená klientovi se zobrazí v adresní řádku prohlížeče, když klient provede nový požadavek na prostředek.

Pokud /resource je přesměrování na /different-resourceserver, server odpoví, že klient by měl získat prostředek se /different-resource stavovým kódem označujícím, že přesměrování je dočasné nebo trvalé.

Koncový bod služby WebAPI se na serveru dočasně změnil z verze 1 (v1) na verzi 2 (v2). Klient odešle do služby požadavek na cestu /v1/api verze 1. Server odešle zpět odpověď 302 (nalezeno) s novou dočasnou cestou pro službu ve verzi 2 /v2/api. Klient odešle službě druhý požadavek na adresu URL přesměrování. Server odpoví stavovým kódem 200 (OK).

Při přesměrování požadavků na jinou adresu URL určete, jestli je přesměrování trvalé nebo dočasné, zadáním stavového kódu s odpovědí:

  • 301 - Moved Permanently Stavový kód se používá, pokud má prostředek novou, trvalou adresu URL a že všechny budoucí požadavky na prostředek by měly používat novou adresu URL. Klient může ukládat odpověď do mezipaměti a opakovaně používat při přijetí stavového kódu 301.

  • Stavový 302 - Found kód se používá, pokud je přesměrování dočasné nebo obecně se může změnit. Stavový kód 302 označuje klientovi, aby neukládal adresu URL a v budoucnu ji používal.

Další informace o stavových kódech najdete v dokumentu RFC 9110: Definice stavových kódů.

Přepsání adresy URL je operace na straně serveru, která poskytuje prostředek z jiné adresy prostředku, než si klient vyžádal. Přepsání adresy URL nevyžaduje odezvu na server. Přepsaná adresa URL se klientovi nevrátí a nezobrazuje se v adresním řádku prohlížeče.

Pokud /resource se přepíše , /different-resourceserver interně načte a vrátí prostředek na adrese /different-resource.

I když klient může být schopen načíst prostředek na přepsané adrese URL, klient není informován, že prostředek existuje na přepsané adrese URL, když odešle požadavek a obdrží odpověď.

Koncový bod služby WebAPI se na serveru změnil z verze 1 (v1) na verzi 2 (v2). Klient odešle do služby požadavek na cestu /v1/api verze 1. Adresa URL požadavku se přepíše pro přístup ke službě v cestě /v2/api verze 2. Služba odpoví klientovi se stavovým kódem 200 (OK).

Ukázková aplikace pro přepis adres URL

Prozkoumejte funkce middlewaru pro přepis adres URL pomocí ukázkové aplikace. Aplikace použije pravidla přesměrování a přepsání a zobrazí přesměrovanou nebo přepsanou adresu URL pro několik scénářů.

Kdy použít middleware pro přepis adres URL

Pokud následující přístupy nevyhovují, použijte middleware pro přepis adres URL:

Při hostování aplikace na HTTP.sys serveru použijte middleware pro přepis adres URL.

Hlavními důvody použití technologií přepisování adres URL na serveru ve službě IIS, Apache a Nginx jsou:

  • Middleware nepodporuje úplné funkce těchto modulů.

    Některé funkce modulů serveru nefungují s projekty ASP.NET Core, jako IsFile jsou například omezení modulu přepisování služby IIS a IsDirectory omezení. V těchto scénářích místo toho použijte middleware.

  • Výkon middlewaru pravděpodobně neodpovídá výkonu modulů.

    Srovnávací testy jsou jediným způsobem, jak zjistit jistotu, který přístup snižuje výkon nejvíce nebo pokud je snížený výkon zanedbatelný.

Rozšíření a možnosti

Vytvořte pravidla přepsání adresy URL a přesměrování vytvořením instance třídy RewriteOptions s rozšiřujícími metodami pro každou pravidla přepsání. Zřetězte více pravidel v pořadí, v jakém se mají zpracovat. Předávají RewriteOptions se do middlewaru pro přepis adresy URL při přidání do kanálu požadavku: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();

V předchozím kódu MethodRules je uživatelsky definovaná třída. Další informace najdete RewriteRules.cs v tomto článku.

Přesměrovat jiné než www na www

Tři možnosti umožňují aplikaci přesměrovat požadavky,www na wwwkteré nejsou požadavky:

Přesměrování adresy URL

Slouží AddRedirect k přesměrování požadavků. První parametr obsahuje regulární výraz .NET (Regex) pro porovnávání na cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr, pokud je k dispozici, určuje stavový kód. Pokud není zadaný stavový kód, výchozí stavový kód je 302 – Nalezeno, což znamená, že se prostředek dočasně přesune nebo nahradí.

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();

V prohlížeči s povolenými vývojářskými nástroji vytvořte požadavek na ukázkovou aplikaci s cestou /redirect-rule/1234/5678. Regulární výraz odpovídá cestě požadavku na redirect-rule/(.*)a cesta je nahrazena /redirected/1234/5678. Adresa URL přesměrování se odešle zpět klientovi se stavovým kódem 302. Prohlížeč vytvoří nový požadavek na adresu URL přesměrování, která se zobrazí v adresní řádku prohlížeče. Vzhledem k tomu, že se žádná pravidla v ukázkové aplikaci neshoduje s adresou URL pro přesměrování:

  • Druhý požadavek obdrží odpověď 200 – OK z aplikace.
  • Text odpovědi zobrazuje adresu URL pro přesměrování.

Při přesměrování adresy URL se na server provede odezva.

Upozorňující

Při vytváření pravidel přesměrování buďte opatrní. Pravidla přesměrování se vyhodnocují při každém požadavku na aplikaci, včetně po přesměrování. Náhodné vytvoření smyčky nekonečných přesměrování je snadné.

Část výrazu obsaženého v závorkách se nazývá skupina zachycení. Tečka (.) výrazu odpovídá libovolnému znaku. Hvězdička (*) označuje shodu s předchozím znakem nula nebo vícekrát. Proto jsou poslední dva segmenty cesty adresy URL zachyceny 1234/5678skupinou (.*)zachycení . Jakákoli hodnota zadaná v adrese URL požadavku po redirect-rule/ zachycení touto jednou skupinou zachycení.

V náhradním řetězci se zachycené skupiny vloží do řetězce se znaménkem dolaru ($) následovaným pořadovým číslem zachycení. První hodnota skupiny zachycení je získána s $1, druhý s $2a pokračuje v sekvenci pro skupiny zachycení v regulárním výrazu. V regulárním výrazu redirect-rule/(.*)pravidla přesměrování existuje pouze jedna zachycená skupina, takže v náhradním řetězci existuje pouze jedna vložená skupina, což je $1. Při použití pravidla se adresa URL stane /redirected/1234/5678.

Zkuste použít /redirect-rule/1234/5678 nástroje prohlížeče na kartě Síť.

Přesměrování adresy URL na zabezpečený koncový bod

Slouží AddRedirectToHttps k přesměrování požadavků HTTP na stejného hostitele a cestu pomocí protokolu HTTPS. Pokud stavový kód není zadaný, middleware se ve výchozím nastavení nastaví na hodnotu 302 – Nalezeno. Pokud port není zadaný:

  • Ve výchozím nastavení se middleware nastaví na null.
  • Schéma se změní na https protokol HTTPS a klient přistupuje k prostředku na portu 443.

Následující příklad ukazuje, jak nastavit stavový kód na 301 - Moved Permanently port HTTPS používaný Kestrel na místním hostiteli a změnit ho na port HTTPS. V produkčním prostředí je port HTTPS nastavený na hodnotu null:

using Microsoft.AspNetCore.Rewrite;
using RewriteRules;

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

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

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

    app.UseRewriter(options);
}

app.UseStaticFiles();

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

app.Run();

Slouží AddRedirectToHttpsPermanent k přesměrování nezabezpečených požadavků na stejného hostitele a cestu se zabezpečeným protokolem HTTPS na portu 443. Middleware nastaví stavový kód na 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();

Poznámka:

Při přesměrování na zabezpečený koncový bod bez požadavku na další pravidla přesměrování doporučujeme použít middleware přesměrování HTTPS. Další informace najdete v tématu Vynucení HTTPS.

Ukázková aplikace ukazuje, jak používat AddRedirectToHttps nebo AddRedirectToHttpsPermanent. Zabezpečte požadavek HTTP na aplikaci na adrese http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz. Při testování přesměrování HTTP na HTTPS pomocí místního hostitele:

  • Použijte adresu URL HTTP, která má jiný port než adresa URL HTTPS. Adresa URL PROTOKOLU HTTP je v Properties/launchSettings.json souboru.
  • s Odebrání z https://localhost/{port} důvodu selhání kvůli tomu, že localhost nereaguje na port HTTPS na http.

Následující obrázek ukazuje obrázek nástrojů prohlížeče F12 požadavku na http://redirect6.azurewebsites.net/iis-rules-rewrite/xyz použití předchozího kódu:

Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi: Přidání přesměrování na HTTPS

Přepsání adresy URL

Slouží AddRewrite k vytvoření pravidla pro přepis adres URL. První parametr obsahuje regulární výraz pro porovnávání v cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr , skipRemainingRules: {true|false}označuje middleware zda přeskočit další přepis pravidla, pokud je aktuální pravidlo použito.

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();

Zkuste požadavek na https://redirect6.azurewebsites.net/rewrite-rule/1234/5678

Stříška (^) na začátku výrazu znamená, že porovnávání začíná na začátku cesty URL.

V předchozím příkladu s pravidlem redirect-rule/(.*)přesměrování neexistuje žádná stříška (^) na začátku regulárního výrazu. Proto všechny znaky mohou předcházet redirect-rule/ v cestě pro úspěšnou shodu.

Cesta Párování
/redirect-rule/1234/5678 Ano
/my-cool-redirect-rule/1234/5678 Ano
/anotherredirect-rule/1234/5678 Yes

Pravidlo přepsání odpovídá ^rewrite-rule/(\d+)/(\d+)pouze cestám, pokud začínají rewrite-rule/na . V následující tabulce si všimněte rozdílu ve shodě.

Cesta Párování
/rewrite-rule/1234/5678 Yes
/my-cool-rewrite-rule/1234/5678 No
/anotherrewrite-rule/1234/5678 Ne

^rewrite-rule/ Za částí výrazu jsou dvě skupiny zachycení , (\d+)/(\d+). Symboly \d odpovídají číslici (číslo). Znaménko plus (+) znamená shodu s jedním nebo více předchozím znakem. Proto musí adresa URL obsahovat číslo následované lomítkem následovaným jiným číslem. Tyto skupiny zachycení se vloží do přepsané adresy URL jako $1 a $2. Řetězec nahrazení pravidla přepsáním umístí zachycené skupiny do řetězce dotazu. Požadovaná cesta /rewrite-rule/1234/5678 se přepíše tak, aby vrátila prostředek na adrese /rewritten?var1=1234&var2=5678. Pokud v původním požadavku existuje řetězec dotazu, zachová se při přepsání adresy URL.

Na server neexistuje žádná zpáteční cesta, která by vrátila prostředek. Pokud prostředek existuje, načte se a vrátí klientovi se stavovým kódem 200 – OK . Vzhledem k tomu, že klient není přesměrován, adresa URL v adresní řádku prohlížeče se nezmění. Klienti nemůžou zjistit, že na serveru došlo k operaci přepsání adresy URL.

Tipy pro zvýšení výkonu pro přepsání a přesměrování adres URL

Nejrychlejší odpověď:

  • Pravidla přepisování objednávek z nejčastěji vyhovujícího pravidla na pravidlo, které odpovídá nejméně často.
  • Kdykoli skipRemainingRules: true je to možné, protože odpovídající pravidla jsou výpočetně náročná a zvyšují dobu odezvy aplikace. Přeskočte zpracování zbývajících pravidel, když dojde ke shodě, a nevyžaduje se žádné další zpracování pravidel.

Upozorňující

Uživatel se zlými úmysly může poskytnout nákladné zpracování vstupu, aby způsoboval RegularExpressions útok na dostupnost služby. ASP.NET rozhraní API architektury Core, která používají RegularExpressions vypršení časového limitu. Například třídy RedirectRule a RewriteRule předávají do jednoho druhého časového limitu.

Apache mod_rewrite

Použití pravidel Apache mod_rewrite s AddApacheModRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Další informace a příklady pravidel mod_rewrite najdete v tématu Apache mod_rewrite.

A StreamReader slouží ke čtení pravidel ze souboru pravidel 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();

Ukázková aplikace přesměruje požadavky z /apache-mod-rules-redirect/(.\*) ./redirected?id=$1 Stavový kód odpovědi je 302 – Nalezeno.

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

Zkuste požadavek na https://redirect6.azurewebsites.net/apache-mod-rules-redirect/1234

Middleware Apache podporuje následující proměnné serveru Apache mod_rewrite:

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

Pravidla modulu přepsání adresy URL služby IIS

Chcete-li použít stejnou sadu pravidel, která se vztahuje na modul přepsání adresy URL služby IIS, použijte AddIISUrlRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Nesměrujte middleware tak, aby při spuštění ve službě Windows Server IIS používal soubor web.config aplikace. U služby IIS by tato pravidla měla být uložena mimo soubor web.config aplikace, aby nedocházelo ke konfliktům s modulem iis Rewrite. Další informace a příklady pravidel modulu přepsání adresy URL služby IIS naleznete v tématu Použití modulu přepsání adresy URL 2.0 a odkazy na konfiguraci modulu přepisu adresy URL.

A StreamReader slouží ke čtení pravidel ze IISUrlRewrite.xml souboru pravidel:

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();

Ukázková aplikace přepisuje požadavky z /iis-rules-rewrite/(.*) do /rewritten?id=$1. Odpověď se odešle klientovi se stavovým kódem 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>

Zkuste požadavek na https://redirect6.azurewebsites.net/iis-rules-rewrite/xyz

Aplikace, které mají aktivní modul pro přepis služby IIS s nakonfigurovanými pravidly na úrovni serveru, která ovlivňují aplikaci nežádoucími způsoby:

  • Zvažte zakázání modulu pro přepsání služby IIS pro aplikaci.
  • Další informace naleznete v tématu Zakázání modulů služby IIS.

Nepodporované funkce

Middleware nepodporuje následující funkce modulu přepsání adresy URL služby IIS:

  • Pravidla pro odchozí provoz
  • Vlastní proměnné serveru
  • Zástupné znaky
  • LogRewrittenUrl

Podporované proměnné serveru

Middleware podporuje následující proměnné serveru modulu pro přepsání adresy URL služby 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 lze získat prostřednictvím PhysicalFileProvider. Tento přístup může poskytovat větší flexibilitu pro umístění souborů pravidel přepsání. Ujistěte se, že jsou soubory pravidel přepsání nasazené na server v zadané cestě.

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

Pravidlo založené na metodách

Slouží Add k implementaci vlastní logiky pravidla v metodě. AddRewriteContextzveřejňuje , který zpřístupňuje HttpContext pro použití v metodách přesměrování. Vlastnost RewriteContext.Result určuje, jak se zpracovává další zpracování kanálu. Nastavte hodnotu na jedno z RuleResult polí popsaných v následující tabulce.

Přepsat výsledek kontextu Akce
RuleResult.ContinueRules (výchozí) Pokračujte v používání pravidel.
RuleResult.EndResponse Ukončete použití pravidel a odešlete odpověď.
RuleResult.SkipRemainingRules Ukončete použití pravidel a odešlete kontext do dalšího middlewaru.
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();

Ukázková aplikace ukazuje metodu, která přesměruje požadavky na cesty, které končí .xml. Při provedení žádosti o /file.xml:

  • Požadavek se přesměruje na /xmlfiles/file.xml
  • Stavový kód je nastaven na 301 - Moved Permanentlyhodnotu . Když prohlížeč vytvoří nový požadavek na /xmlfiles/file.xml, statický soubor Middleware obsluhuje soubor klientovi ze složky wwwroot/xmlfiles . Pro přesměrování explicitně nastavte stavový kód odpovědi. V opačném případě se vrátí stavový kód 200 – OK a v klientovi nedojde k přesměrování.

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;
    }
}

Tento přístup může také přepsat požadavky. Ukázková aplikace ukazuje přepsání cesty pro jakýkoli požadavek na textový soubor, který bude sloužit file.txt textovému souboru ze složky wwwroot. Middleware statického souboru slouží k souboru na základě aktualizované cesty požadavku:

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";
    }
}

Pravidlo založené na IRule

Používá Add se k použití logiky pravidla ve třídě, která implementuje IRule rozhraní. IRule poskytuje větší flexibilitu při používání přístupu založeného na metodách. Třída implementace může obsahovat konstruktor, který umožňuje předávání parametrů pro metodu 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();

Hodnoty parametrů v ukázkové aplikaci a extension jsou newPath kontrolovány tak, aby splňovaly několik podmínek. Musí extension obsahovat hodnotu a hodnota musí být .png, .jpgnebo .gif. newPath Pokud není platný, vyvolá se chybaArgumentException. Pokud je žádost podána image.png, žádost se přesměruje na /png-images/image.png. Pokud je žádost podána image.jpg, žádost se přesměruje na /jpg-images/image.jpg. Stavový kód je nastaven na hodnotu a context.Result je nastaven na 301 - Moved Permanentlyzastavení zpracování pravidel a odeslání odpovědi.

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;
        }
    }
}

Vyzkoušejte:

  • Požadavek PNG: https://redirect6.azurewebsites.net/image.png
  • Žádost JPG: https://redirect6.azurewebsites.net/image.jpg

Příklady regulárních výrazů

Goal Řetězec regulárního výrazu a
Příklad shody
Náhradní řetězec &.
Příklad výstupu
Přepsání cesty do řetězce dotazu ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Pruh koncové lomítko ^path2/(.*)/$
/path2/xyz/
$1
/path2/xyz
Vynucení koncového lomítka ^path3/(.*[^/])$
/path3/xyz
$1/
/path3/xyz/
Vyhněte se přepisování konkrétních požadavků ^(.*)(?<!\.axd)$ nebo
^(?!.*\.axd$)(.*)$
Ano: /path4/resource.htm
Ne: /path4/resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
Změna uspořádání segmentů adres URL path5/(.*)/(.*)/(.*)
path5/1/2/3
path5/$3/$2/$1
path5/3/2/1
Nahrazení segmentu adresy URL ^path6/(.*)/segment2/(.*)
^path6/segment1/segment2/segment3
path6/$1/replaced/$2
/path6/segment1/replaced/segment3

Odkazy v předchozí tabulce používají následující kód nasazený do 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();

Ve většině předchozích ukázek regulárních výrazů se literál path používá k vytvoření jedinečných testovatelných pravidel přepisování nasazené ukázky. Regulární výraz obvykle neobsahuje path. Podívejte se například na tabulku s příklady regulárních výrazů .

Tento dokument představuje přepis adres URL s pokyny k použití middlewaru pro přepis adres URL v aplikacích ASP.NET Core.

Přepsání adresy URL je úprava adres URL požadavků na základě jednoho nebo více předdefinovaných pravidel. Přepsání adresy URL vytvoří abstrakci mezi umístěními prostředků a jejich adresami, takže umístění a adresy nejsou úzce propojené. Přepsání adresy URL je cenné v několika scénářích pro:

  • Přesuňte nebo nahraďte prostředky serveru dočasně nebo trvale a udržujte stabilní lokátory těchto prostředků.
  • Rozdělte zpracování žádostí mezi různé aplikace nebo napříč oblastmi jedné aplikace.
  • Odeberte, přidejte nebo reorganizujte segmenty adres URL u příchozích požadavků.
  • Optimalizace veřejných adres URL pro optimalizaci vyhledávacích webů (SEO).
  • Povolte použití přátelských veřejných adres URL, které návštěvníkům pomůžou předpovědět obsah vrácený žádostí o prostředek.
  • Přesměrujte nezabezpečené požadavky na zabezpečené koncové body.
  • Znemožnit propojení s hotlinkingem, kdy externí web používá hostovaný statický prostředek na jiném webu propojením prostředku s vlastním obsahem.

Poznámka:

Přepsání adresy URL může snížit výkon aplikace. Pokud je to možné, omezte počet a složitost pravidel.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Přesměrování adresy URL a přepsání adresy URL

Rozdíl ve formulaci přesměrování adresy URL a přepsání adresy URL je malý, ale má důležité důsledky pro poskytování prostředků klientům. ASP.NET middlewaru pro přepis adresy URL jádra je schopen splnit potřebu obojího.

Přesměrování adresy URL zahrnuje operaci na straně klienta, kde se klientovi dá pokyn, aby přistupoval k prostředku na jiné adrese než původně požadovaný klient. To vyžaduje odezvu na server. Adresa URL přesměrování vrácená klientovi se zobrazí v adresní řádku prohlížeče, když klient provede nový požadavek na prostředek.

Pokud /resource je přesměrování na /different-resourceserver, server odpoví, že klient by měl získat prostředek se /different-resource stavovým kódem označujícím, že přesměrování je dočasné nebo trvalé.

Koncový bod služby WebAPI se na serveru dočasně změnil z verze 1 (v1) na verzi 2 (v2). Klient odešle do služby požadavek na cestu /v1/api verze 1. Server odešle zpět odpověď 302 (nalezeno) s novou dočasnou cestou pro službu ve verzi 2 /v2/api. Klient odešle službě druhý požadavek na adresu URL přesměrování. Server odpoví stavovým kódem 200 (OK).

Při přesměrování požadavků na jinou adresu URL určete, jestli je přesměrování trvalé nebo dočasné, zadáním stavového kódu s odpovědí:

  • 301 - Moved Permanently Stavový kód se používá, pokud má prostředek novou, trvalou adresu URL a chcete dát klientovi pokyn, aby všechny budoucí požadavky na prostředek měly používat novou adresu URL. Klient může ukládat odpověď do mezipaměti a opakovaně používat při přijetí stavového kódu 301.

  • Stavový kód 302 – Nalezený se používá, pokud je přesměrování dočasné nebo obecně se může změnit. Stavový kód 302 označuje klientovi, aby neukládal adresu URL a v budoucnu ji používal.

Další informace o stavových kódech najdete v dokumentu RFC 9110: Definice stavových kódů.

Přepsání adresy URL je operace na straně serveru, která poskytuje prostředek z jiné adresy prostředku, než si klient vyžádal. Přepsání adresy URL nevyžaduje odezvu na server. Přepsaná adresa URL se klientovi nevrátí a nezobrazuje se v adresním řádku prohlížeče.

Pokud /resource se přepíše , /different-resourceserver interně načte a vrátí prostředek na adrese /different-resource.

I když klient může být schopen načíst prostředek na přepsané adrese URL, klient není informován, že prostředek existuje na přepsané adrese URL, když odešle požadavek a obdrží odpověď.

Koncový bod služby WebAPI se na serveru změnil z verze 1 (v1) na verzi 2 (v2). Klient odešle do služby požadavek na cestu /v1/api verze 1. Adresa URL požadavku se přepíše pro přístup ke službě v cestě /v2/api verze 2. Služba odpoví klientovi se stavovým kódem 200 (OK).

Ukázková aplikace pro přepis adres URL

Pomocí ukázkové aplikace můžete prozkoumat funkce middlewaru pro přepis adres URL. Aplikace použije pravidla přesměrování a přepsání a zobrazí přesměrovanou nebo přepsanou adresu URL pro několik scénářů.

Kdy použít middleware pro přepis adres URL

Pokud nemůžete použít následující přístupy, použijte middleware pro přepis adres URL:

Při hostování aplikace na HTTP.sys serveru použijte middleware pro přepis adres URL.

Hlavními důvody použití technologií přepisování adres URL na serveru ve službě IIS, Apache a Nginx jsou:

  • Middleware nepodporuje úplné funkce těchto modulů.

    Některé funkce modulů serveru nefungují s projekty ASP.NET Core, jako IsFile jsou například omezení modulu přepisování služby IIS a IsDirectory omezení. V těchto scénářích místo toho použijte middleware.

  • Výkon middlewaru pravděpodobně neodpovídá výkonu modulů.

    Srovnávací testy jsou jediným způsobem, jak zjistit, který přístup snižuje výkon nejvíce nebo pokud je snížený výkon zanedbatelný.

Balíček

Middleware pro přepis adres URL poskytuje balíček Microsoft.AspNetCore.Rewrite , který je implicitně součástí aplikací ASP.NET Core.

Rozšíření a možnosti

Vytvořte pravidla přepsání adresy URL a přesměrování vytvořením instance třídy RewriteOptions s rozšiřujícími metodami pro každou pravidla přepsání. Zřetězte více pravidel v pořadí, v jakém je chcete zpracovat. Předávají RewriteOptions se do middlewaru pro přepis adresy URL při přidání do kanálu požadavku: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}"));
}

Přesměrovat jiné než www na www

Tři možnosti umožňují aplikaci přesměrovat požadavky,www na wwwkteré nejsou požadavky:

Přesměrování adresy URL

Slouží AddRedirect k přesměrování požadavků. První parametr obsahuje regulární výraz pro párování na cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr, pokud je k dispozici, určuje stavový kód. Pokud nezadáte stavový kód, výchozí stavový kód je 302 – Nalezeno, což znamená, že se prostředek dočasně přesune nebo nahradí.

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}"));
}

V prohlížeči s povolenými vývojářskými nástroji vytvořte požadavek na ukázkovou aplikaci s cestou /redirect-rule/1234/5678. Regulární výraz odpovídá cestě požadavku na a redirect-rule/(.*)cesta se nahradí znakem /redirected/1234/5678. Adresa URL přesměrování se odešle zpět klientovi se stavovým kódem 302. Prohlížeč vytvoří nový požadavek na adresu URL přesměrování, která se zobrazí v adresní řádku prohlížeče. Vzhledem k tomu, že se žádná pravidla v ukázkové aplikaci neshoduje s adresou URL pro přesměrování:

  • Druhý požadavek obdrží odpověď 200 – OK z aplikace.
  • Text odpovědi zobrazuje adresu URL pro přesměrování.

Při přesměrování adresy URL se na server provede odezva.

Upozorňující

Při vytváření pravidel přesměrování buďte opatrní. Pravidla přesměrování se vyhodnocují při každém požadavku na aplikaci, včetně po přesměrování. Náhodné vytvoření smyčky nekonečných přesměrování je snadné.

Původní žádost: /redirect-rule/1234/5678

Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi: Přidání přesměrování

Část výrazu obsaženého v závorkách se nazývá skupina zachycení. Tečka (.) výrazu odpovídá libovolnému znaku. Hvězdička (*) označuje shodu s předchozím znakem nula nebo vícekrát. Proto jsou poslední dva segmenty cesty adresy URL zachyceny 1234/5678skupinou (.*)zachycení . Jakákoli hodnota, kterou zadáte v adrese URL požadavku, po redirect-rule/ zachycení touto jednou skupinou zachycení.

V náhradním řetězci se zachycené skupiny vloží do řetězce se znaménkem dolaru ($) následovaným pořadovým číslem zachycení. První hodnota skupiny zachycení se získá s $1hodnotou , druhou s $2a budou pokračovat v sekvenci pro skupiny zachycení ve vašem regulárním výrazu. V ukázkové aplikaci existuje pouze jedna zachycená skupina pravidel přesměrování, takže v náhradním řetězci je pouze jedna vložená skupina, což je $1. Při použití pravidla se adresa URL stane /redirected/1234/5678.

Přesměrování adresy URL na zabezpečený koncový bod

Slouží AddRedirectToHttps k přesměrování požadavků HTTP na stejného hostitele a cestu pomocí protokolu HTTPS. Pokud stavový kód není zadaný, middleware se ve výchozím nastavení nastaví na hodnotu 302 – Nalezeno. Pokud port není zadaný:

  • Ve výchozím nastavení se middleware nastaví na null.
  • Schéma se změní na https protokol HTTPS a klient přistupuje k prostředku na portu 443.

Následující příklad ukazuje, jak nastavit stavový kód na 301 - Moved Permanently a změnit port na 5001.

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

    app.UseRewriter(options);
}

Slouží AddRedirectToHttpsPermanent k přesměrování nezabezpečených požadavků na stejného hostitele a cestu se zabezpečeným protokolem HTTPS na portu 443. Middleware nastaví stavový kód na 301 - Moved Permanently.

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

    app.UseRewriter(options);
}

Poznámka:

Při přesměrování na zabezpečený koncový bod bez požadavku na další pravidla přesměrování doporučujeme použít middleware přesměrování HTTPS. Další informace najdete v tématu Vynucení HTTPS .

Ukázková aplikace je schopná předvést, jak používat AddRedirectToHttps nebo AddRedirectToHttpsPermanent. Přidejte metodu rozšíření do souboru RewriteOptions. Vytvořte pro aplikaci nezabezpečený požadavek na libovolnou adresu URL. Zavřete upozornění zabezpečení prohlížeče, že certifikát podepsaný svým držitelem je nedůvěryhodný, nebo vytvořte výjimku, která certifikátu důvěřuje.

Původní žádost pomocí AddRedirectToHttps(301, 5001): http://localhost:5000/secure

Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi: Přidání přesměrování na HTTPS

Původní žádost pomocí AddRedirectToHttpsPermanent: http://localhost:5000/secure

Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi: Přidání přesměrování na trvalé https

Přepsání adresy URL

Slouží AddRewrite k vytvoření pravidla pro přepis adres URL. První parametr obsahuje regulární výraz pro porovnávání v cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr , skipRemainingRules: {true|false}označuje middleware zda přeskočit další přepis pravidla, pokud je aktuální pravidlo použito.

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}"));
}

Původní žádost: /rewrite-rule/1234/5678

Okno prohlížeče s vývojářskými nástroji, které sledují požadavek a odpověď: Přidání přepsání

Karat (^) na začátku výrazu znamená, že porovnávání začíná na začátku cesty URL.

V předchozím příkladu s pravidlem redirect-rule/(.*)přesměrování neexistuje na začátku regulárního výrazu žádný karat (^). Proto všechny znaky mohou předcházet redirect-rule/ v cestě pro úspěšnou shodu.

Cesta Párování
/redirect-rule/1234/5678 Ano
/my-cool-redirect-rule/1234/5678 Ano
/anotherredirect-rule/1234/5678 Yes

Pravidlo přepsání odpovídá ^rewrite-rule/(\d+)/(\d+)pouze cestám, pokud začínají rewrite-rule/na . V následující tabulce si všimněte rozdílu ve shodě.

Cesta Párování
/rewrite-rule/1234/5678 Yes
/my-cool-rewrite-rule/1234/5678 No
/anotherrewrite-rule/1234/5678 Ne

^rewrite-rule/ Za částí výrazu jsou dvě skupiny zachycení , (\d+)/(\d+). Symboly \d odpovídají číslici (číslo). Znaménko plus (+) znamená shodu s jedním nebo více předchozím znakem. Proto musí adresa URL obsahovat číslo následované lomítkem následovaným jiným číslem. Tyto skupiny zachycení se vloží do přepsané adresy URL jako $1 a $2. Řetězec nahrazení pravidla přepsáním umístí zachycené skupiny do řetězce dotazu. Požadovaná cesta /rewrite-rule/1234/5678 je přepsána pro získání prostředku na /rewritten?var1=1234&var2=5678adrese . Pokud v původním požadavku existuje řetězec dotazu, zachová se při přepsání adresy URL.

Na server neexistuje žádná zpáteční cesta k získání prostředku. Pokud prostředek existuje, načte se a vrátí klientovi se stavovým kódem 200 – OK . Vzhledem k tomu, že klient není přesměrován, adresa URL v adresní řádku prohlížeče se nezmění. Klienti nemůžou zjistit, že na serveru došlo k operaci přepsání adresy URL.

Poznámka:

Kdykoli skipRemainingRules: true je to možné, protože odpovídající pravidla jsou výpočetně náročná a zvyšují dobu odezvy aplikace. Nejrychlejší odezva aplikace:

  • Pravidla přepisování objednávek z nejčastěji vyhovujícího pravidla na pravidlo, které odpovídá nejméně často.
  • Přeskočte zpracování zbývajících pravidel, když dojde ke shodě, a nevyžaduje se žádné další zpracování pravidel.

Apache mod_rewrite

Použití pravidel Apache mod_rewrite s AddApacheModRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Další informace a příklady pravidel mod_rewrite najdete v tématu Apache mod_rewrite.

A StreamReader slouží ke čtení pravidel ze souboru pravidel 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}"));
}

Ukázková aplikace přesměruje požadavky z /apache-mod-rules-redirect/(.\*) ./redirected?id=$1 Stavový kód odpovědi je 302 – Nalezeno.

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

Původní žádost: /apache-mod-rules-redirect/1234

Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi: Přidání přesměrování Apache mod

Middleware podporuje následující proměnné serveru Apache mod_rewrite:

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

Pravidla modulu přepsání adresy URL služby IIS

Chcete-li použít stejnou sadu pravidel, která se vztahuje na modul přepsání adresy URL služby IIS, použijte AddIISUrlRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Nesměrujte middleware tak, aby při spuštění ve službě Windows Server IIS používal soubor web.config aplikace. U služby IIS by tato pravidla měla být uložena mimo soubor web.config aplikace, aby nedocházelo ke konfliktům s modulem iis Rewrite. Další informace a příklady pravidel modulu přepsání adresy URL služby IIS naleznete v tématu Použití modulu přepsání adresy URL 2.0 a odkazy na konfiguraci modulu přepisu adresy URL.

A StreamReader slouží ke čtení pravidel ze IISUrlRewrite.xml souboru pravidel:

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}"));
}

Ukázková aplikace přepisuje požadavky z /iis-rules-rewrite/(.*) do /rewritten?id=$1. Odpověď se odešle klientovi se stavovým kódem 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>

Původní žádost: /iis-rules-rewrite/1234

Okno prohlížeče s vývojářskými nástroji, které sledují požadavek a odpověď: Přidání přepsání adresy URL služby IIS

Pokud máte aktivní modul pro přepis služby IIS s nakonfigurovanými pravidly na úrovni serveru, která by ovlivnila vaši aplikaci nežádoucími způsoby, můžete pro aplikaci zakázat modul pro přepis služby IIS. Další informace naleznete v tématu Zakázání modulů služby IIS.

Nepodporované funkce

Middleware nepodporuje následující funkce modulu přepsání adresy URL služby IIS:

  • Pravidla pro odchozí provoz
  • Vlastní proměnné serveru
  • Zástupné znaky
  • LogRewrittenUrl

Podporované proměnné serveru

Middleware podporuje následující proměnné serveru modulu pro přepsání adresy URL služby 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

Poznámka:

Můžete také získat IFileProvider prostřednictvím PhysicalFileProvider. Tento přístup může poskytovat větší flexibilitu pro umístění souborů pravidel přepsání. Ujistěte se, že jsou soubory pravidel přepsání nasazené na server v zadané cestě.

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

Pravidlo založené na metodách

Slouží Add k implementaci vlastní logiky pravidla v metodě. AddRewriteContextzveřejňuje , který zpřístupňuje HttpContext pro použití ve vaší metodě. RewriteContext.Result určuje, jak se zpracovává další zpracování kanálu. Nastavte hodnotu na jedno z RuleResult polí popsaných v následující tabulce.

Přepsat výsledek kontextu Akce
RuleResult.ContinueRules (výchozí) Pokračujte v používání pravidel.
RuleResult.EndResponse Ukončete použití pravidel a odešlete odpověď.
RuleResult.SkipRemainingRules Ukončete použití pravidel a odešlete kontext do dalšího middlewaru.
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}"));
}

Ukázková aplikace ukazuje metodu, která přesměruje požadavky na cesty, které končí .xml. Pokud je žádost podána /file.xml, žádost se přesměruje na /xmlfiles/file.xml. Stavový kód je nastaven na 301 - Moved Permanentlyhodnotu . Když prohlížeč vytvoří nový požadavek na /xmlfiles/file.xml, statický soubor Middleware obsluhuje soubor klientovi ze složky wwwroot/xmlfiles . Pro přesměrování explicitně nastavte stavový kód odpovědi. V opačném případě se vrátí stavový kód 200 – OK a v klientovi nedojde k přesměrování.

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;
    }
}

Tento přístup může také přepsat požadavky. Ukázková aplikace ukazuje přepsání cesty pro jakýkoli požadavek na textový soubor, který bude sloužit file.txt textovému souboru ze složky wwwroot. Middleware statického souboru slouží k souboru na základě aktualizované cesty požadavku:

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";
    }
}

Pravidlo založené na IRule

Používá Add se k použití logiky pravidla ve třídě, která implementuje IRule rozhraní. IRule poskytuje větší flexibilitu při používání přístupu založeného na metodách. Třída implementace může obsahovat konstruktor, který umožňuje předat parametry pro metodu 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}"));
}

Hodnoty parametrů v ukázkové aplikaci a extension jsou newPath kontrolovány tak, aby splňovaly několik podmínek. Musí extension obsahovat hodnotu a hodnota musí být .png, .jpgnebo .gif. newPath Pokud není platný, vyvolá se chybaArgumentException. Pokud je žádost podána image.png, žádost se přesměruje na /png-images/image.png. Pokud je žádost podána image.jpg, žádost se přesměruje na /jpg-images/image.jpg. Stavový kód je nastaven na hodnotu a context.Result je nastaven na 301 - Moved Permanentlyzastavení zpracování pravidel a odeslání odpovědi.

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;
        }
    }
}

Původní žádost: /image.png

Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi na image.png

Původní žádost: /image.jpg

Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi na image.jpg

Příklady regulárních výrazů

Goal Řetězec regulárního výrazu a
Příklad shody
Náhradní řetězec &.
Příklad výstupu
Přepsání cesty do řetězce dotazu ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Pruh koncové lomítko (.*)/$
/path/
$1
/path
Vynucení koncového lomítka (.*[^/])$
/path
$1/
/path/
Vyhněte se přepisování konkrétních požadavků ^(.*)(?<!\.axd)$ nebo ^(?!.*\.axd$)(.*)$
Ano: /resource.htm
Ne: /resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
Změna uspořádání segmentů adres URL path/(.*)/(.*)/(.*)
path/1/2/3
path/$3/$2/$1
path/3/2/1
Nahrazení segmentu adresy URL ^(.*)/segment2/(.*)
/segment1/segment2/segment3
$1/replaced/$2
/segment1/replaced/segment3

Tento dokument představuje přepis adres URL s pokyny k použití middlewaru pro přepis adres URL v aplikacích ASP.NET Core.

Přepsání adresy URL je úprava adres URL požadavků na základě jednoho nebo více předdefinovaných pravidel. Přepsání adresy URL vytvoří abstrakci mezi umístěními prostředků a jejich adresami, takže umístění a adresy nejsou úzce propojené. Přepsání adresy URL je cenné v několika scénářích pro:

  • Přesuňte nebo nahraďte prostředky serveru dočasně nebo trvale a udržujte stabilní lokátory těchto prostředků.
  • Rozdělte zpracování žádostí mezi různé aplikace nebo napříč oblastmi jedné aplikace.
  • Odeberte, přidejte nebo reorganizujte segmenty adres URL u příchozích požadavků.
  • Optimalizace veřejných adres URL pro optimalizaci vyhledávacích webů (SEO).
  • Povolte použití přátelských veřejných adres URL, které návštěvníkům pomůžou předpovědět obsah vrácený žádostí o prostředek.
  • Přesměrujte nezabezpečené požadavky na zabezpečené koncové body.
  • Znemožnit propojení s hotlinkingem, kdy externí web používá hostovaný statický prostředek na jiném webu propojením prostředku s vlastním obsahem.

Poznámka:

Přepsání adresy URL může snížit výkon aplikace. Pokud je to možné, omezte počet a složitost pravidel.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Přesměrování adresy URL a přepsání adresy URL

Rozdíl ve formulaci přesměrování adresy URL a přepsání adresy URL je malý, ale má důležité důsledky pro poskytování prostředků klientům. ASP.NET middlewaru pro přepis adresy URL jádra je schopen splnit potřebu obojího.

Přesměrování adresy URL zahrnuje operaci na straně klienta, kde se klientovi dá pokyn, aby přistupoval k prostředku na jiné adrese než původně požadovaný klient. To vyžaduje odezvu na server. Adresa URL přesměrování vrácená klientovi se zobrazí v adresní řádku prohlížeče, když klient provede nový požadavek na prostředek.

Pokud /resource je přesměrování na /different-resourceserver, server odpoví, že klient by měl získat prostředek se /different-resource stavovým kódem označujícím, že přesměrování je dočasné nebo trvalé.

Koncový bod služby WebAPI se na serveru dočasně změnil z verze 1 (v1) na verzi 2 (v2). Klient odešle do služby požadavek na cestu /v1/api verze 1. Server odešle zpět odpověď 302 (nalezeno) s novou dočasnou cestou pro službu ve verzi 2 /v2/api. Klient odešle službě druhý požadavek na adresu URL přesměrování. Server odpoví stavovým kódem 200 (OK).

Při přesměrování požadavků na jinou adresu URL určete, jestli je přesměrování trvalé nebo dočasné, zadáním stavového kódu s odpovědí:

  • 301 - Moved Permanently Stavový kód se používá, pokud má prostředek novou, trvalou adresu URL a chcete dát klientovi pokyn, aby všechny budoucí požadavky na prostředek měly používat novou adresu URL. Klient může ukládat odpověď do mezipaměti a opakovaně používat při přijetí stavového kódu 301.

  • Stavový kód 302 – Nalezený se používá, pokud je přesměrování dočasné nebo obecně se může změnit. Stavový kód 302 označuje klientovi, aby neukládal adresu URL a v budoucnu ji používal.

Další informace o stavových kódech najdete v dokumentu RFC 9110: Definice stavových kódů.

Přepsání adresy URL je operace na straně serveru, která poskytuje prostředek z jiné adresy prostředku, než si klient vyžádal. Přepsání adresy URL nevyžaduje odezvu na server. Přepsaná adresa URL se klientovi nevrátí a nezobrazuje se v adresním řádku prohlížeče.

Pokud /resource se přepíše , /different-resourceserver interně načte a vrátí prostředek na adrese /different-resource.

I když klient může být schopen načíst prostředek na přepsané adrese URL, klient není informován, že prostředek existuje na přepsané adrese URL, když odešle požadavek a obdrží odpověď.

Koncový bod služby WebAPI se na serveru změnil z verze 1 (v1) na verzi 2 (v2). Klient odešle do služby požadavek na cestu /v1/api verze 1. Adresa URL požadavku se přepíše pro přístup ke službě v cestě /v2/api verze 2. Služba odpoví klientovi se stavovým kódem 200 (OK).

Ukázková aplikace pro přepis adres URL

Pomocí ukázkové aplikace můžete prozkoumat funkce middlewaru pro přepis adres URL. Aplikace použije pravidla přesměrování a přepsání a zobrazí přesměrovanou nebo přepsanou adresu URL pro několik scénářů.

Kdy použít middleware pro přepsání adresy URL

Pokud nemůžete použít následující přístupy, použijte middleware pro přepis adres URL:

Také použijte middleware, když je aplikace hostovaná na HTTP.sys serveru (dříve označované jako WebListener).

Hlavními důvody použití technologií přepisování adres URL na serveru ve službě IIS, Apache a Nginx jsou:

  • Middleware nepodporuje úplné funkce těchto modulů.

    Některé funkce modulů serveru nefungují s projekty ASP.NET Core, jako IsFile jsou například omezení modulu přepisování služby IIS a IsDirectory omezení. V těchto scénářích místo toho použijte middleware.

  • Výkon middlewaru pravděpodobně neodpovídá výkonu modulů.

    Srovnávací testy jsou jediným způsobem, jak zjistit, který přístup snižuje výkon nejvíce nebo pokud je snížený výkon zanedbatelný.

Balíček

Pokud chcete do projektu zahrnout middleware, přidejte do souboru projektu odkaz na balíček Microsoft.AspNetCore.App metabalíku , který obsahuje balíček Microsoft.AspNetCore.Rewrite .

Pokud metabalíč nepoužíváte Microsoft.AspNetCore.App , přidejte do balíčku odkaz na Microsoft.AspNetCore.Rewrite projekt.

Rozšíření a možnosti

Vytvořte pravidla přepsání adresy URL a přesměrování vytvořením instance třídy RewriteOptions s rozšiřujícími metodami pro každou pravidla přepsání. Zřetězte více pravidel v pořadí, v jakém je chcete zpracovat. Předávají RewriteOptions se do middlewaru pro přepis adresy URL při přidání do kanálu požadavku: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}"));
}

Přesměrovat jiné než www na www

Tři možnosti umožňují aplikaci přesměrovat požadavky,www na wwwkteré nejsou požadavky:

Přesměrování adresy URL

Slouží AddRedirect k přesměrování požadavků. První parametr obsahuje regulární výraz pro párování na cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr, pokud je k dispozici, určuje stavový kód. Pokud nezadáte stavový kód, výchozí stavový kód je 302 – Nalezeno, což znamená, že se prostředek dočasně přesune nebo nahradí.

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}"));
}

V prohlížeči s povolenými vývojářskými nástroji vytvořte požadavek na ukázkovou aplikaci s cestou /redirect-rule/1234/5678. Regulární výraz odpovídá cestě požadavku na a redirect-rule/(.*)cesta se nahradí znakem /redirected/1234/5678. Adresa URL přesměrování se odešle zpět klientovi se stavovým kódem 302. Prohlížeč vytvoří nový požadavek na adresu URL přesměrování, která se zobrazí v adresní řádku prohlížeče. Vzhledem k tomu, že se žádná pravidla v ukázkové aplikaci neshoduje s adresou URL pro přesměrování:

  • Druhý požadavek obdrží odpověď 200 – OK z aplikace.
  • Text odpovědi zobrazuje adresu URL pro přesměrování.

Při přesměrování adresy URL se na server provede odezva.

Upozorňující

Při vytváření pravidel přesměrování buďte opatrní. Pravidla přesměrování se vyhodnocují při každém požadavku na aplikaci, včetně po přesměrování. Náhodné vytvoření smyčky nekonečných přesměrování je snadné.

Původní žádost: /redirect-rule/1234/5678

Přidat přesměrování: Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi

Část výrazu obsaženého v závorkách se nazývá skupina zachycení. Tečka (.) výrazu odpovídá libovolnému znaku. Hvězdička (*) označuje shodu s předchozím znakem nula nebo vícekrát. Proto jsou poslední dva segmenty cesty adresy URL zachyceny 1234/5678skupinou (.*)zachycení . Jakákoli hodnota, kterou zadáte v adrese URL požadavku, po redirect-rule/ zachycení touto jednou skupinou zachycení.

V náhradním řetězci se zachycené skupiny vloží do řetězce se znaménkem dolaru ($) následovaným pořadovým číslem zachycení. První hodnota skupiny zachycení se získá s $1hodnotou , druhou s $2a budou pokračovat v sekvenci pro skupiny zachycení ve vašem regulárním výrazu. V ukázkové aplikaci existuje pouze jedna zachycená skupina pravidel přesměrování, takže v náhradním řetězci je pouze jedna vložená skupina, což je $1. Při použití pravidla se adresa URL stane /redirected/1234/5678.

Přesměrování adresy URL na zabezpečený koncový bod

Slouží AddRedirectToHttps k přesměrování požadavků HTTP na stejného hostitele a cestu pomocí protokolu HTTPS. Pokud stavový kód není zadaný, middleware se ve výchozím nastavení nastaví na hodnotu 302 – Nalezeno. Pokud port není zadaný:

  • Ve výchozím nastavení se middleware nastaví na null.
  • Schéma se změní na https protokol HTTPS a klient přistupuje k prostředku na portu 443.

Následující příklad ukazuje, jak nastavit stavový kód na 301 - Moved Permanently a změnit port na 5001.

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

    app.UseRewriter(options);
}

Slouží AddRedirectToHttpsPermanent k přesměrování nezabezpečených požadavků na stejného hostitele a cestu se zabezpečeným protokolem HTTPS na portu 443. Middleware nastaví stavový kód na 301 - Moved Permanently.

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

    app.UseRewriter(options);
}

Poznámka:

Při přesměrování na zabezpečený koncový bod bez požadavku na další pravidla přesměrování doporučujeme použít middleware přesměrování HTTPS. Další informace najdete v tématu Vynucení HTTPS .

Ukázková aplikace je schopná předvést, jak používat AddRedirectToHttps nebo AddRedirectToHttpsPermanent. Přidejte metodu rozšíření do souboru RewriteOptions. Vytvořte pro aplikaci nezabezpečený požadavek na libovolnou adresu URL. Zavřete upozornění zabezpečení prohlížeče, že certifikát podepsaný svým držitelem je nedůvěryhodný, nebo vytvořte výjimku, která certifikátu důvěřuje.

Původní žádost pomocí AddRedirectToHttps(301, 5001): http://localhost:5000/secure

Přidání přesměrování na HTTPS: Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi

Původní žádost pomocí AddRedirectToHttpsPermanent: http://localhost:5000/secure

Přidání přesměrování na trvalé https: Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi

Přepsání adresy URL

Slouží AddRewrite k vytvoření pravidla pro přepis adres URL. První parametr obsahuje regulární výraz pro porovnávání v cestě příchozí adresy URL. Druhým parametrem je náhradní řetězec. Třetí parametr , skipRemainingRules: {true|false}označuje middleware zda přeskočit další přepis pravidla, pokud je aktuální pravidlo použito.

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}"));
}

Původní žádost: /rewrite-rule/1234/5678

Přidání přepsání: Okno prohlížeče s vývojářskými nástroji, které sledují požadavek a odpověď

Karat (^) na začátku výrazu znamená, že porovnávání začíná na začátku cesty URL.

V předchozím příkladu s pravidlem redirect-rule/(.*)přesměrování neexistuje na začátku regulárního výrazu žádný karat (^). Proto všechny znaky mohou předcházet redirect-rule/ v cestě pro úspěšnou shodu.

Cesta Párování
/redirect-rule/1234/5678 Ano
/my-cool-redirect-rule/1234/5678 Ano
/anotherredirect-rule/1234/5678 Yes

Pravidlo přepsání odpovídá ^rewrite-rule/(\d+)/(\d+)pouze cestám, pokud začínají rewrite-rule/na . V následující tabulce si všimněte rozdílu ve shodě.

Cesta Párování
/rewrite-rule/1234/5678 Yes
/my-cool-rewrite-rule/1234/5678 No
/anotherrewrite-rule/1234/5678 Ne

^rewrite-rule/ Za částí výrazu jsou dvě skupiny zachycení , (\d+)/(\d+). Symboly \d odpovídají číslici (číslo). Znaménko plus (+) znamená shodu s jedním nebo více předchozím znakem. Proto musí adresa URL obsahovat číslo následované lomítkem následovaným jiným číslem. Tyto skupiny zachycení se vloží do přepsané adresy URL jako $1 a $2. Řetězec nahrazení pravidla přepsáním umístí zachycené skupiny do řetězce dotazu. Požadovaná cesta /rewrite-rule/1234/5678 je přepsána pro získání prostředku na /rewritten?var1=1234&var2=5678adrese . Pokud v původním požadavku existuje řetězec dotazu, zachová se při přepsání adresy URL.

Na server neexistuje žádná zpáteční cesta k získání prostředku. Pokud prostředek existuje, načte se a vrátí klientovi se stavovým kódem 200 – OK . Vzhledem k tomu, že klient není přesměrován, adresa URL v adresní řádku prohlížeče se nezmění. Klienti nemůžou zjistit, že na serveru došlo k operaci přepsání adresy URL.

Poznámka:

Kdykoli skipRemainingRules: true je to možné, protože odpovídající pravidla jsou výpočetně náročná a zvyšují dobu odezvy aplikace. Nejrychlejší odezva aplikace:

  • Pravidla přepisování objednávek z nejčastěji vyhovujícího pravidla na pravidlo, které odpovídá nejméně často.
  • Přeskočte zpracování zbývajících pravidel, když dojde ke shodě, a nevyžaduje se žádné další zpracování pravidel.

Apache mod_rewrite

Použití pravidel Apache mod_rewrite s AddApacheModRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Další informace a příklady pravidel mod_rewrite najdete v tématu Apache mod_rewrite.

A StreamReader slouží ke čtení pravidel ze souboru pravidel 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}"));
}

Ukázková aplikace přesměruje požadavky z /apache-mod-rules-redirect/(.\*) ./redirected?id=$1 Stavový kód odpovědi je 302 – Nalezeno.

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

Původní žádost: /apache-mod-rules-redirect/1234

Přidání přesměrování Apache mod: Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi

Middleware podporuje následující proměnné serveru Apache mod_rewrite:

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

Pravidla modulu přepsání adresy URL služby IIS

Chcete-li použít stejnou sadu pravidel, která se vztahuje na modul přepsání adresy URL služby IIS, použijte AddIISUrlRewrite. Ujistěte se, že je soubor pravidel nasazený s aplikací. Nesměrujte middleware tak, aby při spuštění ve službě Windows Server IIS používal soubor web.config aplikace. U služby IIS by tato pravidla měla být uložena mimo soubor web.config aplikace, aby nedocházelo ke konfliktům s modulem iis Rewrite. Další informace a příklady pravidel modulu přepsání adresy URL služby IIS naleznete v tématu Použití modulu přepsání adresy URL 2.0 a odkazy na konfiguraci modulu přepisu adresy URL.

A StreamReader slouží ke čtení pravidel ze IISUrlRewrite.xml souboru pravidel:

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}"));
}

Ukázková aplikace přepisuje požadavky z /iis-rules-rewrite/(.*) do /rewritten?id=$1. Odpověď se odešle klientovi se stavovým kódem 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>

Původní žádost: /iis-rules-rewrite/1234

Přidání přepsání adresy URL služby IIS: Okno prohlížeče s vývojářskými nástroji, které sledují požadavek a odpověď

Pokud máte aktivní modul pro přepis služby IIS s nakonfigurovanými pravidly na úrovni serveru, která by ovlivnila vaši aplikaci nežádoucími způsoby, můžete pro aplikaci zakázat modul pro přepis služby IIS. Další informace naleznete v tématu Zakázání modulů služby IIS.

Nepodporované funkce

Middleware vydaný s ASP.NET Core 2.x nepodporuje následující funkce modulu přepsání adresy URL služby IIS:

  • Pravidla pro odchozí provoz
  • Vlastní proměnné serveru
  • Zástupné znaky
  • LogRewrittenUrl

Podporované proměnné serveru

Middleware podporuje následující proměnné serveru modulu pro přepsání adresy URL služby 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

Poznámka:

Můžete také získat IFileProvider prostřednictvím PhysicalFileProvider. Tento přístup může poskytovat větší flexibilitu pro umístění souborů pravidel přepsání. Ujistěte se, že jsou soubory pravidel přepsání nasazené na server v zadané cestě.

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

Pravidlo založené na metodách

Slouží Add k implementaci vlastní logiky pravidla v metodě. AddRewriteContextzveřejňuje , který zpřístupňuje HttpContext pro použití ve vaší metodě. RewriteContext.Result určuje, jak se zpracovává další zpracování kanálu. Nastavte hodnotu na jedno z RuleResult polí popsaných v následující tabulce.

Přepsat výsledek kontextu Akce
RuleResult.ContinueRules (výchozí) Pokračujte v používání pravidel.
RuleResult.EndResponse Ukončete použití pravidel a odešlete odpověď.
RuleResult.SkipRemainingRules Ukončete použití pravidel a odešlete kontext do dalšího middlewaru.
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}"));
}

Ukázková aplikace ukazuje metodu, která přesměruje požadavky na cesty, které končí .xml. Pokud je žádost podána /file.xml, žádost se přesměruje na /xmlfiles/file.xml. Stavový kód je nastaven na 301 - Moved Permanentlyhodnotu . Když prohlížeč vytvoří nový požadavek na /xmlfiles/file.xml, statický soubor Middleware obsluhuje soubor klientovi ze složky wwwroot/xmlfiles . Pro přesměrování explicitně nastavte stavový kód odpovědi. V opačném případě se vrátí stavový kód 200 – OK a v klientovi nedojde k přesměrování.

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;
    }
}

Tento přístup může také přepsat požadavky. Ukázková aplikace ukazuje přepsání cesty pro jakýkoli požadavek na textový soubor, který bude sloužit file.txt textovému souboru ze složky wwwroot. Middleware statického souboru slouží k souboru na základě aktualizované cesty požadavku:

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";
    }
}

Pravidlo založené na IRule

Používá Add se k použití logiky pravidla ve třídě, která implementuje IRule rozhraní. IRule poskytuje větší flexibilitu při používání přístupu založeného na metodách. Třída implementace může obsahovat konstruktor, který umožňuje předat parametry pro metodu 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}"));
}

Hodnoty parametrů v ukázkové aplikaci a extension jsou newPath kontrolovány tak, aby splňovaly několik podmínek. Musí extension obsahovat hodnotu a hodnota musí být .png, .jpgnebo .gif. newPath Pokud není platný, vyvolá se chybaArgumentException. Pokud je žádost podána image.png, žádost se přesměruje na /png-images/image.png. Pokud je žádost podána image.jpg, žádost se přesměruje na /jpg-images/image.jpg. Stavový kód je nastaven na hodnotu a context.Result je nastaven na 301 - Moved Permanentlyzastavení zpracování pravidel a odeslání odpovědi.

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;
        }
    }
}

Původní žádost: /image.png

Pro image.png: Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi

Původní žádost: /image.jpg

Pro image.jpg: Okno prohlížeče s vývojářskými nástroji, které sledují požadavky a odpovědi

Příklady regulárních výrazů

Goal Řetězec regulárního výrazu a
Příklad shody
Náhradní řetězec &.
Příklad výstupu
Přepsání cesty do řetězce dotazu ^path/(.*)/(.*)
/path/abc/123
path?var1=$1&var2=$2
/path?var1=abc&var2=123
Pruh koncové lomítko (.*)/$
/path/
$1
/path
Vynucení koncového lomítka (.*[^/])$
/path
$1/
/path/
Vyhněte se přepisování konkrétních požadavků ^(.*)(?<!\.axd)$ nebo ^(?!.*\.axd$)(.*)$
Ano: /resource.htm
Ne: /resource.axd
rewritten/$1
/rewritten/resource.htm
/resource.axd
Změna uspořádání segmentů adres URL path/(.*)/(.*)/(.*)
path/1/2/3
path/$3/$2/$1
path/3/2/1
Nahrazení segmentu adresy URL ^(.*)/segment2/(.*)
/segment1/segment2/segment3
$1/replaced/$2
/segment1/replaced/segment3

Další materiály