Povolit žádosti mezi zdroji (CORS) v ASP.NET Core
Od Rick Anderson a Kirka Larkin
tento článek popisuje, jak v aplikaci ASP.NET Core povolit CORS.
Zabezpečení prohlížeče brání webové stránce v tom, aby prováděla požadavky na jinou doménu než ta, která tuto webovou stránku obsluhoval. Toto omezení se nazývá zásady stejného původu. Zásady stejného původce brání škodlivému webu v čtení citlivých dat z jiné lokality. V některých případech můžete chtít umožnit jiným webům, aby vaši aplikaci mohli vytvářet žádosti o více zdrojů. Další informace najdete v článku věnovaném Mozilla CORS.
Sdílení prostředků mezi zdroji (CORS):
- Je standard W3C, který umožňuje serveru zmírnit zásady stejného zdroje.
- Nejedná se o funkci zabezpečení, CORS zabezpečení CORS zmírnit. Rozhraní API není bezpečnější díky povolení CORS. Další informace najdete v tématu jak CORS funguje.
- Umožňuje serveru explicitně povolit některé žádosti mezi zdroji a současně odmítat jiné.
- Je bezpečnější a pružnější než u předchozích technik, jako třeba JSONP.
Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)
Stejný původ
Dvě adresy URL mají stejný původ, pokud mají identická schémata, hostitele a porty (RFC 6454).
Tyto dvě adresy URL mají stejný původ:
https://example.com/foo.htmlhttps://example.com/bar.html
Tyto adresy URL mají různé zdroje, než jsou předchozí dvě adresy URL:
https://example.net: Odlišná doménahttps://www.example.com/foo.html: Odlišná subdoménahttp://example.com/foo.html: Odlišné schémahttps://example.com:9000/foo.html: Jiný port
Povolení CORS
Existují tři způsoby, jak povolit CORS:
- V middlewaru pomocí pojmenované zásady nebo výchozí zásady.
- Použití Směrování koncového bodu.
- S atributem [EnableCors] .
Použití atributu [EnableCors] s pojmenovanou zásadou poskytuje ovládací prvek nejlepší v omezení koncových bodů, které podporují CORS.
Upozornění
UseCors musí být volána ve správném pořadí. Další informace najdete v tématu pořadí middlewaru. Například UseCors musí být volána před UseResponseCaching při použití UseResponseCaching .
Každý přístup je podrobně popsaný v následujících částech.
CORS s pojmenovanými zásadami a middlewarem
Middleware CORS zpracovává požadavky mezi zdroji. Následující kód aplikuje zásadu CORS na všechny koncové body aplikace se zadanými zdroji:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
// services.AddResponseCaching();
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();
app.MapControllers();
app.Run();
Předchozí kód:
- Nastaví název zásady na
_myAllowSpecificOrigins. Název zásady je libovolný. - Zavolá UseCors metodu rozšíření a určí
_myAllowSpecificOriginszásadu CORS.UseCorsPřidá middleware CORS. VoláníUseCorsmusí být umístěno poUseRouting, ale předUseAuthorization. Další informace najdete v tématu pořadí middlewaru. - Volání AddCors s výrazem lambda. Lambda převezme CorsPolicyBuilder objekt. Možnosti konfigurace, například
WithOrigins, jsou popsány dále v tomto článku. - Povolí
_myAllowSpecificOriginszásadu CORS pro všechny koncové body řadiče. Pokud chcete použít zásadu CORS na konkrétní koncové body, podívejte se na téma Směrování koncového bodu . - při použití middlewaru Ukládání do mezipaměti middlewarevolejte UseCors před UseResponseCaching .
Při směrování koncových bodů musí být MIDDLEWARe CORS nakonfigurované tak, aby se spustilo mezi voláními UseRouting a UseEndpoints .
Pokyny k testování kódu podobného předchozímu kódu naleznete v tématu test CORS .
AddCorsVolání metody přidá služby CORS do kontejneru služby aplikace:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
// services.AddResponseCaching();
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();
app.MapControllers();
app.Run();
Další informace najdete v tématu Možnosti zásad CORS v tomto dokumentu.
CorsPolicyBuilderMetody mohou být zřetězeny, jak je znázorněno v následujícím kódu:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();
app.MapControllers();
app.Run();
Poznámka: Zadaná adresa URL nesmí obsahovat koncové lomítko ( / ). Pokud adresa URL končí / , porovnávání se vrátí false a nevrátí se žádné záhlaví.
CORS s výchozími zásadami a middlewarem
Následující zvýrazněný kód umožňuje výchozí zásadu CORS:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.Run();
Předchozí kód aplikuje výchozí zásadu CORS na všechny koncové body řadiče.
Povolení CORS s směrováním koncových bodů
Povolení CORS na základě jednotlivých koncových bodů pomocí nepodporuje RequireCors Automatické požadavky na kontrolu před výstupem. další informace najdete v tomto GitHub problému a testování CORS pomocí směrování koncových bodů a [HttpOptions].
S směrováním koncových bodů je možné CORS povolit na základě jednotlivých koncových bodů pomocí RequireCors sady rozšiřujících metod:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
builder.Services.AddControllers();
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/echo",
context => context.Response.WriteAsync("echo"))
.RequireCors(MyAllowSpecificOrigins);
endpoints.MapControllers()
.RequireCors(MyAllowSpecificOrigins);
endpoints.MapGet("/echo2",
context => context.Response.WriteAsync("echo2"));
endpoints.MapRazorPages();
});
app.Run();
V předchozím kódu:
app.UseCorspovoluje middleware CORS. Vzhledem k tomu, že výchozí zásady nejsou nakonfigurované,app.UseCors()nepovolí CORS samotné./echoKoncové body řadiče a umožňují žádosti mezi zdroji pomocí zadaných zásad./echo2Razor Koncové body stránky a nepovolují požadavky mezi zdroji, protože nebyly zadány žádné výchozí zásady.
Atribut [DisableCors] nevypne CORS , která byla povolená směrováním koncových bodů s RequireCors .
Pokyny k testování kódu podobného předchozímu najdete v tématu test CORS pomocí směrování koncových bodů a [HttpOptions] .
Povolení CORS s atributy
Povolení CORS s atributem [EnableCors] a použití pojmenované zásady pouze na koncové body, které vyžadují CORS, poskytuje ovládací prvek nejlepší.
Atribut [EnableCors] poskytuje alternativu k použití CORS globálně. [EnableCors]Atribut umožňuje CORS pro vybrané koncové body místo všech koncových bodů:
[EnableCors]Určuje výchozí zásadu.[EnableCors("{Policy String}")]Určuje pojmenovanou zásadu.
[EnableCors]Atribut lze použít pro:
- Razor Page
PageModel - Controller
- Metoda akce kontroleru
U řadičů, modelů stránek nebo metod akcí lze použít různé zásady s [EnableCors] atributem. Pokud je [EnableCors] atribut použit na řadič, model stránky nebo metodu akce a CORS je v middleware povolená, uplatní se obě zásady. Doporučujeme před kombinováním zásad. Použijte [EnableCors] atribut nebo middleware, nikoli oba ve stejné aplikaci.
Následující kód používá pro každou metodu jinou zásadu:
[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
// GET api/values
[EnableCors("AnotherPolicy")]
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "green widget", "red widget" };
}
// GET api/values/5
[EnableCors("Policy1")]
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return id switch
{
1 => "green widget",
2 => "red widget",
_ => NotFound(),
};
}
}
Následující kód vytvoří dvě zásady CORS:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("Policy1",
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("AnotherPolicy",
builder =>
{
builder.WithOrigins("http://www.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.Run();
Pro ovládací prvek nejlepší pro omezení požadavků CORS:
- Použijte
[EnableCors("MyPolicy")]s pojmenovanou zásadou. - Nedefinujte výchozí zásady.
- Nepoužívejte Směrování koncových bodů.
Kód v další části splňuje předchozí seznam.
Pokyny k testování kódu podobného předchozímu kódu naleznete v tématu test CORS .
Zakázání CORS
Atribut [DisableCors] zakáže rozhraní CORS, které bylo povoleno směrováním koncových bodů.
Následující kód definuje zásadu CORS "MyPolicy" :
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com")
.WithMethods("PUT", "DELETE", "GET");
});
});
builder.Services.AddControllers();
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.MapRazorPages();
app.Run();
Následující kód zakáže CORS pro GetValues2 akci:
[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public IActionResult Get() =>
ControllerContext.MyDisplayRouteInfo();
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// PUT api/values/5
[HttpPut("{id}")]
public IActionResult Put(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/values/GetValues2
[DisableCors]
[HttpGet("{action}")]
public IActionResult GetValues2() =>
ControllerContext.MyDisplayRouteInfo();
}
Předchozí kód:
- Nepovoluje CORS s směrováním koncových bodů.
- Nedefinuje výchozí zásady CORS.
- K povolení zásad CORS pro kontroler používá [EnableCors("MyPolicy")].
"MyPolicy" - Zakáže CORS pro
GetValues2metodu .
Pokyny k testování předchozího kódu najdete v tématu Testování CORS.
Možnosti zásad CORS
Tato část popisuje různé možnosti, které je možné nastavit v zásadách CORS:
- Nastavení povolených původů
- Nastavení povolených metod HTTP
- Nastavení povolených hlaviček požadavků
- Nastavení zveřejněných hlaviček odpovědi
- Přihlašovací údaje v požadavcích napříč zdroji
- Nastavení předběžného času vypršení platnosti
AddPolicyse volá v souboru Program.cs. U některých možností může být užitečné si nejprve přečíst část Jak CORS funguje.
Nastavení povolených původů
AllowAnyOrigin: Povoluje požadavky CORS ze všech původů s libovolným schématem ( http nebo https ). AllowAnyOrigin je nezabezpečený, protože jakýkoli web může na aplikaci provádět požadavky mezi zdroji.
Poznámka
Určení a AllowAnyOrigin je nezabezpečená konfigurace a může vést ke padělání požadavků AllowCredentials mezi weby. Služba CORS vrátí neplatnou odpověď CORS, pokud je aplikace nakonfigurovaná s oběma metodami.
AllowAnyOrigin ovlivňuje předběžné požadavky a Access-Control-Allow-Origin hlavičku. Další informace najdete v části Předběžné požadavky.
SetIsOriginAllowedToAllowWildcardSubdomains: Nastaví vlastnost zásady jako funkci, která umožňuje, aby původy odpovídaly nakonfigurované zástupné doméně při vyhodnocování, jestli IsOriginAllowed je původ povolený.
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("https://*.example.com")
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Nastavení povolených metod HTTP
- Umožňuje libovolnou metodu HTTP:
- Ovlivňuje předběžné požadavky a
Access-Control-Allow-Methodshlavičku. Další informace najdete v části Předběžné požadavky.
Nastavení povolených hlaviček požadavků
Pokud chcete v požadavku CORS povolit posílání konkrétních hlaviček, které se nazývají hlavičky požadavku autora,zavolejte a WithHeaders zadejte povolené hlavičky:
using Microsoft.Net.Http.Headers;
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Pokud chcete povolit všechny hlavičky požadavku autora,zavolejte AllowAnyHeader :
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
AllowAnyHeadermá vliv na předběžné požadavky a hlavičku Access-Control-Request-Headers. Další informace najdete v části Předběžné požadavky.
Shoda zásad middlewaru CORS s konkrétními hlavičkami určenými parametrem je možná pouze v případě, že hlavičky odeslané v přesně odpovídají WithHeaders Access-Control-Request-Headers hlavičkám uvedeným v WithHeaders .
Představte si například aplikaci nakonfigurovanou takto:
app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));
Middleware CORS odmítne předběžnou žádost s následující hlavičkou požadavku, protože Content-Language (HeaderNames.ContentLanguage) není uvedená v WithHeaders :
Access-Control-Request-Headers: Cache-Control, Content-Language
Aplikace vrátí odpověď 200 OK, ale neposíleje zpět hlavičky CORS. Proto se prohlížeč nepokusí o požadavek mezi zdroji.
Nastavení zveřejněných hlaviček odpovědi
Ve výchozím nastavení prohlížeč aplikaci nezpřístupňuje všechny hlavičky odpovědi. Další informace najdete v tématu Sdílení prostředků mezi zdroji W3C (terminologie): Jednoduchá hlavička odpovědi.
Hlavičky odpovědi, které jsou ve výchozím nastavení k dispozici:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
Specifikace CORS volá tyto hlavičky s jednoduchými hlavičkami odpovědi. Pokud chcete aplikaci zobrazit další hlavičky, zavolejte WithExposedHeaders :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyExposeResponseHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Přihlašovací údaje v požadavcích mezi zdroji
Přihlašovací údaje vyžadují zvláštní zpracování v požadavku CORS. Ve výchozím nastavení prohlížeč neposíleje přihlašovací údaje s požadavkem mezi zdroji. Mezi přihlašovací cookie údaje patří schémata ověřování s a HTTP. Pokud chcete odeslat přihlašovací údaje s požadavkem mezi zdroji, musí klient nastavit XMLHttpRequest.withCredentials na true hodnotu .
Přímé XMLHttpRequest použití:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
Pomocí jQuery:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
Pomocí rozhraní Fetch API:
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Server musí přihlašovací údaje povolit. Pokud chcete povolit přihlašovací údaje mezi zdroji, zavolejte AllowCredentials :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyMyAllowCredentialsPolicy",
builder =>
{
builder.WithOrigins("http://example.com")
.AllowCredentials();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Odpověď HTTP obsahuje hlavičku , která prohlížeči říká, že server povoluje přihlašovací údaje pro požadavek Access-Control-Allow-Credentials mezi zdroji.
Pokud prohlížeč odešle přihlašovací údaje, ale odpověď neobsahuje platnou hlavičku, prohlížeč odpověď aplikaci nezpřístupní a požadavek napříč zdroji Access-Control-Allow-Credentials selže.
Povolení přihlašovacích údajů mezi zdroji je bezpečnostním rizikem. Web v jiné doméně může poslat přihlašovací údaje přihlášených uživatelů do aplikace jménem uživatele bez vědomí uživatele.
Specifikace CORS také uvádí, že nastavení původu na (všechny původy) je neplatné, pokud "*" Access-Control-Allow-Credentials je hlavička k dispozici.
Předběžné požadavky
U některých požadavků CORS odešle prohlížeč před vytvořením skutečného požadavku další požadavek OPTIONS. Tento požadavek se nazývá předběžná žádost. Prohlížeč může předběžné požadavky přeskočit, pokud jsou splněny všechny následující podmínky:
- Metoda požadavku je GET, HEAD nebo POST.
- Aplikace nenastaví jiné hlavičky požadavků než
Accept, , , neboAccept-LanguageContent-LanguageContent-TypeLast-Event-ID. - Pokud
Content-Typeje hlavička nastavená, má jednu z následujících hodnot:application/x-www-form-urlencodedmultipart/form-datatext/plain
Pravidlo pro hlavičky požadavku nastavené pro požadavek klienta se vztahuje na hlavičky, které aplikace nastavuje setRequestHeader voláním pro XMLHttpRequest objekt . Specifikace CORS volá tyto hlavičky author request headers. Pravidlo se nevztahuje na hlavičky, které může prohlížeč nastavit, například User-Agent Host , nebo Content-Length .
Následuje příklad odpovědi podobné předběžnému požadavku z tlačítka [Put test] v části Test CORS tohoto dokumentu.
General:
Request URL: https://cors3.azurewebsites.net/api/values/5
Request Method: OPTIONS
Status Code: 204 No Content
Response Headers:
Access-Control-Allow-Methods: PUT,DELETE,GET
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f8...8;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Vary: Origin
Request Headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Method: PUT
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0
Předběžné požadavky používají metodu HTTP OPTIONS. Může obsahovat následující hlavičky:
- Access-Control-Request-Method:Metoda HTTP, která se použije pro vlastní požadavek.
- Access-Control-Request-Headers: Seznam hlaviček požadavků, které aplikace nastavuje na skutečný požadavek. Jak jsme uvedli dříve, nezahrnuje hlavičky, které prohlížeč nastavuje, například
User-Agent. - Řízení přístupu – Povolení metod
Pokud je předběžná žádost zamítnuta, aplikace vrátí odpověď, ale nenastaví 200 OK hlavičky CORS. Proto se prohlížeč nepokusí o požadavek mezi zdroji. Příklad zamítnuté předběžné žádosti najdete v části Test CORS tohoto dokumentu.
Při použití nástrojů F12 se v aplikaci konzoly v závislosti na prohlížeči zobrazí chyba podobná jedné z následujících:
- Firefox: Blokovaný požadavek napříč zdroji: Stejná zásada původu zakáže čtení vzdáleného prostředku na adrese
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5. (Důvod: Požadavek CORS nebyl úspěšný). Další informace - Chromium na základě: Zásady CORS zablokovaly přístup k načtení ze zdroje: Odpověď na předběžnou žádost neprojde kontrolou řízení přístupu: V požadovaném prostředku není k dispozici hlavička https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 https://cors3.azurewebsites.net Access-Control-Allow-Origin. Pokud pro vaše potřeby slouží neprůhledná odpověď, nastavte režim požadavku na no-cors, aby se načítal prostředek se zakázaným CORS.
Pokud chcete povolit konkrétní hlavičky, volejte WithHeaders :
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowHeadersPolicy",
builder =>
{
builder.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Pokud chcete povolit všechny hlavičky požadavku autora,zavolejte AllowAnyHeader :
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowAllHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Prohlížeče nejsou konzistentní v tom, jak nastavují Access-Control-Request-Headers . Pokud:
- Hlavičky jsou nastavené na cokoli jiného než
"*" - AllowAnyHeader má název : Zahrnte alespoň , a a plus vlastní
AcceptContent-TypeOriginhlavičky, které chcete podporovat.
Automatický předběžné kód požadavku
Když se použijí zásady CORS:
- Globálně voláním
app.UseCorsv souboru Program.cs. - Pomocí
[EnableCors]atributu .
ASP.NET Core na předběžnou žádost OPTIONS.
Povolení CORS pro každý koncový bod pomocí v současné době RequireCors nepodporuje automatické předběžné požadavky.
Toto chování je znázorněno v části Testování CORS tohoto dokumentu.
Atribut [HttpOptions] pro předběžné požadavky
Pokud je CORS povolený s příslušnou zásadou, ASP.NET Core automaticky reaguje na předběžné požadavky CORS. V některých scénářích tomu tak nemusí být. Například použití CORS se směrováním koncového bodu.
Následující kód používá atribut [HttpOptions] k vytvoření koncových bodů pro požadavky OPTIONS:
[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
// OPTIONS: api/TodoItems2/5
[HttpOptions("{id}")]
public IActionResult PreflightRoute(int id)
{
return NoContent();
}
// OPTIONS: api/TodoItems2
[HttpOptions]
public IActionResult PreflightRoute()
{
return NoContent();
}
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return BadRequest();
}
return ControllerContext.MyDisplayRouteInfo(id);
}
Pokyny k testování předchozího kódu najdete v tématu Testování CORS se směrováním koncového bodu a [HttpOptions].
Nastavení předběžného času vypršení platnosti
Hlavička určuje, jak dlouho lze odpověď na předběžnou žádost ukládat Access-Control-Max-Age do mezipaměti. Pokud chcete nastavit tuto hlavičku, zavolejte SetPreflightMaxAge :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MySetPreflightExpirationPolicy",
builder =>
{
builder.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
});
builder.Services.AddControllers();
var app = builder.Build();
Jak CORS funguje
Tato část popisuje, co se děje v požadavku CORS na úrovni zpráv HTTP.
- CORS není funkce zabezpečení. CORS je standard W3C, který umožňuje serveru uvolnit zásady stejného původu.
- Například aktér se zlými úmysly by mohl na vašem webu použít skriptování mezi weby (XSS) a provést požadavek mezi weby na svém webu s podporou CORS, aby mohl odcinout informace.
- Povolením CORS není rozhraní API bezpečnější.
- Vynucení CORS je na klientovi (prohlížeči). Server provede požadavek a vrátí odpověď. Je to klient, který vrací chybu a blokuje odpověď. Například kterýkoli z následujících nástrojů zobrazí odpověď serveru:
- Fiddler
- Postman
- .NET HttpClient
- Webový prohlížeč zadáním adresy URL do adresního řádku.
- Vynucení CORS je na klientovi (prohlížeči). Server provede požadavek a vrátí odpověď. Je to klient, který vrací chybu a blokuje odpověď. Například kterýkoli z následujících nástrojů zobrazí odpověď serveru:
- Je to způsob, jak může server povolit prohlížečům spouštět požadavky XHR nebo Fetch API, které by jinak mohly být zakázané.
- Prohlížeče bez CORS nemůže dělat požadavky mezi zdroji. Před CORS se k obcházení tohoto omezení použil JSONP. JSONP XHR používá, k přijetí odpovědi
<script>používá značku . Skripty je možné načíst mezi zdroji.
- Prohlížeče bez CORS nemůže dělat požadavky mezi zdroji. Před CORS se k obcházení tohoto omezení použil JSONP. JSONP XHR používá, k přijetí odpovědi
Specifikace CORS zavedla několik nových hlaviček PROTOKOLU HTTP, které umožňují požadavky mezi zdroji. Pokud prohlížeč podporuje CORS, nastaví tyto hlavičky automaticky pro požadavky různého původu. K povolení CORS se vlastní javascriptový kód nevyžaduje.
Testovací tlačítko PUT na nasazené ukázce
Následuje příklad požadavku mezi zdroji z testovacího tlačítka Hodnoty na https://cors1.azurewebsites.net/api/values . OriginHlavička:
- Poskytuje doménu webu, který požadavek zažádá.
- Vyžaduje se a musí se lišit od hostitele.
Obecná záhlaví
Request URL: https://cors1.azurewebsites.net/api/values
Request Method: GET
Status Code: 200 OK
Hlavičky odpovědi
Content-Encoding: gzip
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Powered-By: ASP.NET
Hlavičky požadavku
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: cors1.azurewebsites.net
Origin: https://cors3.azurewebsites.net
Referer: https://cors3.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 ...
V OPTIONS požadavcích server nastaví hlavičku Response v Access-Control-Allow-Origin: {allowed origin} odpovědi. Například nasazený ukázkový požadavekna tlačítko Odstranit [EnableCors] OPTIONS obsahuje následující hlavičky:
Obecná záhlaví
Request URL: https://cors3.azurewebsites.net/api/TodoItems2/MyDelete2/5
Request Method: OPTIONS
Status Code: 204 No Content
Hlavičky odpovědi
Access-Control-Allow-Headers: Content-Type,x-custom-header
Access-Control-Allow-Methods: PUT,DELETE,GET,OPTIONS
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors3.azurewebsites.net
Vary: Origin
X-Powered-By: ASP.NET
Hlavičky požadavku
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: DELETE
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/test?number=2
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0
V předchozích hlavičkách Response server v odpovědi nastaví hlavičku Access-Control-Allow-Origin. Hodnota https://cors1.azurewebsites.net této hlavičky odpovídá Origin hlavičce z požadavku.
Pokud se volá , vrátí se hodnota AllowAnyOrigin Access-Control-Allow-Origin: * se zástupným znakem . AllowAnyOrigin umožňuje jakýkoli původ.
Pokud odpověď hlavičku neobsahuje, požadavek mezi zdroji Access-Control-Allow-Origin selže. Konkrétně prohlížeč požadavek zakáže. I když server vrátí úspěšnou odpověď, prohlížeč odpověď nezíská pro klientskou aplikaci.
Zobrazení požadavků OPTIONS
Prohlížeče Chrome a Edge ve výchozím nastavení nezískaly požadavky OPTIONS na kartě sítě v nástrojích F12. Zobrazení požadavků OPTIONS v těchto prohlížečích:
chrome://flags/#out-of-blink-corsneboedge://flags/#out-of-blink-cors- zakažte příznak .
- restart (restartovat).
Firefox ve výchozím nastavení zobrazuje požadavky OPTIONS.
CORS ve službě IIS
Při nasazování do služby IIS musí CORS běžet před Windows, pokud server není nakonfigurovaný tak, aby povoloval anonymní přístup. Pro podporu tohoto scénáře je potřeba nainstalovat a nakonfigurovat modul CORS služby IIS pro aplikaci.
Testování CORS
Ukázkový soubor ke stažení obsahuje kód pro testování CORS. Podívejte se, jak stáhnout . Ukázka je projekt rozhraní API s Razor přidanými stránkami:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com",
"https://cors1.azurewebsites.net",
"https://cors3.azurewebsites.net",
"https://localhost:44398",
"https://localhost:5001")
.WithMethods("PUT", "DELETE", "GET");
});
});
builder.Services.AddControllers();
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.MapRazorPages();
app.Run();
Upozornění
WithOrigins("https://localhost:<port>");by se mělo používat jenom k testování ukázkové aplikace podobné ukázkovému kódu pro stažení.
Následující kód ValuesController poskytuje koncové body pro testování:
[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public IActionResult Get() =>
ControllerContext.MyDisplayRouteInfo();
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// PUT api/values/5
[HttpPut("{id}")]
public IActionResult Put(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/values/GetValues2
[DisableCors]
[HttpGet("{action}")]
public IActionResult GetValues2() =>
ControllerContext.MyDisplayRouteInfo();
}
MyDisplayRouteInfo poskytuje balíček Rick.Docs.Samples.RouteInfo NuGet a zobrazuje informace o trasách.
Otestujte předchozí vzorový kód pomocí jednoho z následujících přístupů:
- Použijte nasazenou ukázkovou aplikaci na adrese https://cors3.azurewebsites.net/ . Ukázku není potřeba stahovat.
- Spusťte ukázku s
dotnet runpoužitím výchozí adresy URLhttps://localhost:5001. - Spusťte ukázku z Visual Studio s portem nastaveným na 44398 pro adresu URL
https://localhost:44398.
Použití prohlížeče s nástroji F12:
Vyberte tlačítko Hodnoty a zkontrolujte záhlaví na kartě Síť.
Vyberte testovací tlačítko PUT. Pokyny k zobrazení požadavku OPTIONS najdete v tématu Zobrazení požadavků OPTIONS. Test PUT vytvoří dva požadavky, předběžné požadavky OPTIONS a požadavek PUT.
Výběrem
GetValues2 [DisableCors]tlačítka aktivujte neúspěšný požadavek CORS. Jak je uvedeno v dokumentu, odpověď vrátí 200 úspěchů, ale požadavek CORS není proveden. Výběrem karty Konzola zobrazíte chybu CORS. V závislosti na prohlížeči se zobrazí chyba podobná následující:Zásady CORS zablokovaly přístup k načtení ze zdroje: V požadovaném prostředku není k dispozici hlavička
'https://cors1.azurewebsites.net/api/values/GetValues2''https://cors3.azurewebsites.net'Access-Control-Allow-Origin. Pokud neprůhledná odpověď slouží vašim potřebám, nastavte režim požadavku na no-cors, aby se načítal prostředek se zakázaným CORS.
Koncové body s podporou CORS je možné testovat pomocí nástroje, jako je curl, Fiddlernebo Postman. Při použití nástroje se původ požadavku určený hlavičkou musí lišit od hostitele, který Origin požadavek přijímá. Pokud požadavek není mezi zdroji založený na hodnotě Origin hlavičky:
- Ke zpracování požadavku není potřeba middleware CORS.
- Hlavičky CORS se v odpovědi nevrátily.
Následující příkaz použije curl k vydání požadavku OPTIONS s informacemi:
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
Testování CORS se směrováním koncového bodu a [HttpOptions]
Povolení CORS pro každý koncový bod pomocí v současné době RequireCors nepodporuje automatické předběžné požadavky. Zvažte následující kód, který používá směrování koncových bodů k povolení CORS:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com",
"https://cors1.azurewebsites.net",
"https://cors3.azurewebsites.net",
"https://localhost:44398",
"https://localhost:5001")
.WithMethods("PUT", "DELETE", "GET");
});
});
builder.Services.AddControllers();
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.MapRazorPages();
app.Run();
Následující seznam TodoItems1Controller poskytuje koncové body pro testování:
[Route("api/[controller]")]
[ApiController]
public class TodoItems1Controller : ControllerBase
{
// PUT: api/TodoItems1/5
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return Content($"ID = {id}");
}
return ControllerContext.MyDisplayRouteInfo(id);
}
// Delete: api/TodoItems1/5
[HttpDelete("{id}")]
public IActionResult MyDelete(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/TodoItems1
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors]
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
// Delete: api/TodoItems1/MyDelete2/5
[EnableCors]
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Otestujte předchozí kód ze stránky testu nasazené ukázky.
Tlačítka Delete [EnableCors] a GET [EnableCors] jsou úspěšná, protože koncové body mají předběžné požadavky a reagují [EnableCors] na ně. Ostatní koncové body se nezdaří. Tlačítko GET selže, protože JavaScript odešle:
headers: {
"Content-Type": "x-custom-header"
},
Následující kód poskytuje podobné koncové body, ale obsahuje explicitní kód pro TodoItems2Controller reakci na požadavky OPTIONS:
[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
// OPTIONS: api/TodoItems2/5
[HttpOptions("{id}")]
public IActionResult PreflightRoute(int id)
{
return NoContent();
}
// OPTIONS: api/TodoItems2
[HttpOptions]
public IActionResult PreflightRoute()
{
return NoContent();
}
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return BadRequest();
}
return ControllerContext.MyDisplayRouteInfo(id);
}
// [EnableCors] // Not needed as OPTIONS path provided
[HttpDelete("{id}")]
public IActionResult MyDelete(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
[EnableCors] // Rquired for this path
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors] // Rquired for this path
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Otestujte předchozí kód ze stránky testu nasazené ukázky. V rozevíracím seznamu Kontroler vyberte Předběžné a pak Nastavit kontroler. Všechna volání CORS do TodoItems2Controller koncových bodů jsou úspěšná.
Další zdroje informací
Od Rick Anderson a Kirka Larkin
tento článek popisuje, jak v aplikaci ASP.NET Core povolit CORS.
Zabezpečení prohlížeče brání webové stránce v tom, aby prováděla požadavky na jinou doménu než ta, která tuto webovou stránku obsluhoval. Toto omezení se nazývá zásady stejného původu. Zásady stejného původce brání škodlivému webu v čtení citlivých dat z jiné lokality. V některých případech můžete chtít umožnit jiným webům, aby vaši aplikaci mohli vytvářet žádosti o více zdrojů. Další informace najdete v článku věnovaném Mozilla CORS.
Sdílení prostředků mezi zdroji (CORS):
- Je standard W3C, který umožňuje serveru zmírnit zásady stejného zdroje.
- Nejedná se o funkci zabezpečení, CORS zabezpečení CORS zmírnit. Rozhraní API není bezpečnější díky povolení CORS. Další informace najdete v tématu jak CORS funguje.
- Umožňuje serveru explicitně povolit některé žádosti mezi zdroji a současně odmítat jiné.
- Je bezpečnější a pružnější než u předchozích technik, jako třeba JSONP.
Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)
Stejný původ
Dvě adresy URL mají stejný původ, pokud mají identická schémata, hostitele a porty (RFC 6454).
Tyto dvě adresy URL mají stejný původ:
https://example.com/foo.htmlhttps://example.com/bar.html
Tyto adresy URL mají různé zdroje, než jsou předchozí dvě adresy URL:
https://example.net: Odlišná doménahttps://www.example.com/foo.html: Odlišná subdoménahttp://example.com/foo.html: Odlišné schémahttps://example.com:9000/foo.html: Jiný port
Povolení CORS
Existují tři způsoby, jak povolit CORS:
- V middlewaru pomocí pojmenované zásady nebo výchozí zásady.
- Použití Směrování koncového bodu.
- S atributem [EnableCors] .
Použití atributu [EnableCors] s pojmenovanou zásadou poskytuje ovládací prvek nejlepší v omezení koncových bodů, které podporují CORS.
Upozornění
UseCors musí být volána ve správném pořadí. Další informace najdete v tématu pořadí middlewaru. Například UseCors musí být volána před UseResponseCaching při použití UseResponseCaching .
Každý přístup je podrobně popsaný v následujících částech.
CORS s pojmenovanými zásadami a middlewarem
Middleware CORS zpracovává požadavky mezi zdroji. Následující kód aplikuje zásadu CORS na všechny koncové body aplikace se zadanými zdroji:
public class Startup
{
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
// services.AddResponseCaching();
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
// app.UseResponseCaching();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Předchozí kód:
- Nastaví název zásady na
_myAllowSpecificOrigins. Název zásady je libovolný. - Zavolá UseCors metodu rozšíření a určí
_myAllowSpecificOriginszásadu CORS.UseCorsPřidá middleware CORS. VoláníUseCorsmusí být umístěno poUseRouting, ale předUseAuthorization. Další informace najdete v tématu pořadí middlewaru. - Volání AddCors s výrazem lambda. Lambda převezme CorsPolicyBuilder objekt. Možnosti konfigurace, například
WithOrigins, jsou popsány dále v tomto článku. - Povolí
_myAllowSpecificOriginszásadu CORS pro všechny koncové body řadiče. Pokud chcete použít zásadu CORS na konkrétní koncové body, podívejte se na téma Směrování koncového bodu . - při použití middlewaru Ukládání do mezipaměti middlewarevolejte UseCors před UseResponseCaching .
Při směrování koncových bodů musí být MIDDLEWARe CORS nakonfigurované tak, aby se spustilo mezi voláními UseRouting a UseEndpoints .
Pokyny k testování kódu podobného předchozímu kódu naleznete v tématu test CORS .
AddCorsVolání metody přidá služby CORS do kontejneru služby aplikace:
public class Startup
{
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
// services.AddResponseCaching();
services.AddControllers();
}
Další informace najdete v tématu Možnosti zásad CORS v tomto dokumentu.
CorsPolicyBuilderMetody mohou být zřetězeny, jak je znázorněno v následujícím kódu:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllers();
}
Poznámka: Zadaná adresa URL nesmí obsahovat koncové lomítko ( / ). Pokud adresa URL končí / , porovnávání se vrátí false a nevrátí se žádné záhlaví.
CORS s výchozími zásadami a middlewarem
Následující zvýrazněný kód umožňuje výchozí zásadu CORS:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Předchozí kód aplikuje výchozí zásadu CORS na všechny koncové body řadiče.
Povolení CORS s směrováním koncových bodů
Povolení CORS na základě jednotlivých koncových bodů pomocí nepodporuje RequireCors Automatické požadavky na kontrolu před výstupem. další informace najdete v tomto GitHub problému a testování CORS pomocí směrování koncových bodů a [HttpOptions].
S směrováním koncových bodů je možné CORS povolit na základě jednotlivých koncových bodů pomocí RequireCors sady rozšiřujících metod:
public class Startup
{
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
services.AddControllers();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/echo",
context => context.Response.WriteAsync("echo"))
.RequireCors(MyAllowSpecificOrigins);
endpoints.MapControllers()
.RequireCors(MyAllowSpecificOrigins);
endpoints.MapGet("/echo2",
context => context.Response.WriteAsync("echo2"));
endpoints.MapRazorPages();
});
}
}
V předchozím kódu:
app.UseCorspovoluje middleware CORS. Vzhledem k tomu, že výchozí zásady nejsou nakonfigurované,app.UseCors()nepovolí CORS samotné./echoKoncové body řadiče a umožňují žádosti mezi zdroji pomocí zadaných zásad./echo2Razor Koncové body stránky a nepovolují požadavky mezi zdroji, protože nebyly zadány žádné výchozí zásady.
Atribut [DisableCors] nevypne CORS , která byla povolená směrováním koncových bodů s RequireCors .
Pokyny k testování kódu podobného předchozímu najdete v tématu test CORS pomocí směrování koncových bodů a [HttpOptions] .
Povolení CORS s atributy
Povolení CORS s atributem [EnableCors] a použití pojmenované zásady pouze na koncové body, které vyžadují CORS, poskytuje ovládací prvek nejlepší.
Atribut [EnableCors] poskytuje alternativu k použití CORS globálně. [EnableCors]Atribut umožňuje CORS pro vybrané koncové body místo všech koncových bodů:
[EnableCors]Určuje výchozí zásadu.[EnableCors("{Policy String}")]Určuje pojmenovanou zásadu.
[EnableCors]Atribut lze použít pro:
- Razor Page
PageModel - Controller
- Metoda akce kontroleru
U řadičů, modelů stránek nebo metod akcí lze použít různé zásady s [EnableCors] atributem. Pokud je [EnableCors] atribut použit na řadič, model stránky nebo metodu akce a CORS je v middleware povolená, uplatní se obě zásady. Doporučujeme před kombinováním zásad. Použijte [EnableCors] atribut nebo middleware, nikoli oba ve stejné aplikaci.
Následující kód používá pro každou metodu jinou zásadu:
[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
// GET api/values
[EnableCors("AnotherPolicy")]
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "green widget", "red widget" };
}
// GET api/values/5
[EnableCors("Policy1")]
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return id switch
{
1 => "green widget",
2 => "red widget",
_ => NotFound(),
};
}
}
Následující kód vytvoří dvě zásady CORS:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("Policy1",
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("AnotherPolicy",
builder =>
{
builder.WithOrigins("http://www.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Pro ovládací prvek nejlepší pro omezení požadavků CORS:
- Použijte
[EnableCors("MyPolicy")]s pojmenovanou zásadou. - Nedefinujte výchozí zásady.
- Nepoužívejte Směrování koncových bodů.
Kód v další části splňuje předchozí seznam.
Pokyny k testování kódu podobného předchozímu kódu naleznete v tématu test CORS .
Zakázání CORS
Atribut [DisableCors] zakáže rozhraní CORS, které bylo povoleno směrováním koncových bodů.
Následující kód definuje zásadu CORS "MyPolicy" :
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com")
.WithMethods("PUT", "DELETE", "GET");
});
});
services.AddControllers();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
}
Následující kód zakáže CORS pro GetValues2 akci:
[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public IActionResult Get() =>
ControllerContext.MyDisplayRouteInfo();
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// PUT api/values/5
[HttpPut("{id}")]
public IActionResult Put(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/values/GetValues2
[DisableCors]
[HttpGet("{action}")]
public IActionResult GetValues2() =>
ControllerContext.MyDisplayRouteInfo();
}
Předchozí kód:
- Nepovoluje CORS s směrováním koncových bodů.
- Nedefinuje výchozí zásadu CORS.
- Pro povolení zásad CORS pro kontroler používá [EnableCors ("MyPolicy")]
"MyPolicy". - Zakáže CORS pro
GetValues2metodu.
Pokyny k testování předchozího kódu najdete v tématu Testování CORS.
Možnosti zásad CORS
Tato část popisuje různé možnosti, které je možné nastavit v zásadách CORS:
- Nastavení povolených původů
- Nastavení povolených metod HTTP
- Nastavení povolených hlaviček požadavků
- Nastavení zveřejněných hlaviček odpovědi
- Přihlašovací údaje v požadavcích napříč zdroji
- Nastavení předběžného času vypršení platnosti
AddPolicy se volá v Startup.ConfigureServices . U některých možností může být užitečné si nejprve přečíst část Jak CORS funguje.
Nastavení povolených původů
AllowAnyOrigin: Povoluje požadavky CORS ze všech původů s libovolným schématem ( http nebo https ). AllowAnyOrigin je nezabezpečený, protože jakýkoli web může na aplikaci provádět požadavky mezi zdroji.
Poznámka
Určení a AllowAnyOrigin je nezabezpečená konfigurace a může vést ke padělání žádostí mezi AllowCredentials weby. Služba CORS vrátí neplatnou odpověď CORS, pokud je aplikace nakonfigurovaná s oběma metodami.
AllowAnyOrigin ovlivňuje předběžné požadavky a Access-Control-Allow-Origin hlavičku. Další informace najdete v části Předběžné požadavky.
SetIsOriginAllowedToAllowWildcardSubdomains: Nastaví vlastnost zásady jako funkci, která umožňuje, aby původy odpovídaly nakonfigurované zástupné doméně při vyhodnocování, jestli IsOriginAllowed je původ povolený.
options.AddPolicy("MyAllowSubdomainPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
Nastavení povolených metod HTTP
- Umožňuje libovolnou metodu HTTP:
- Ovlivňuje předběžné požadavky a
Access-Control-Allow-Methodshlavičku. Další informace najdete v části Předběžné požadavky.
Nastavení povolených hlaviček požadavků
Pokud chcete v požadavku CORS povolit posílání konkrétních hlaviček, které se nazývají hlavičky požadavku autora,zavolejte a WithHeaders zadejte povolené hlavičky:
options.AddPolicy("MyAllowHeadersPolicy",
builder =>
{
// requires using Microsoft.Net.Http.Headers;
builder.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Pokud chcete povolit všechny hlavičky požadavku autora,zavolejte AllowAnyHeader :
options.AddPolicy("MyAllowAllHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
AllowAnyHeadermá vliv na předběžné požadavky a hlavičku Access-Control-Request-Headers. Další informace najdete v části Předběžné požadavky.
Shoda zásad middlewaru CORS s konkrétními hlavičkami určenými parametrem je možná pouze v případě, že hlavičky odeslané v přesně odpovídají WithHeaders Access-Control-Request-Headers hlavičkám uvedeným v WithHeaders .
Představte si například aplikaci nakonfigurovanou takto:
app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));
Middleware CORS odmítne předběžnou žádost s následující hlavičkou požadavku, protože Content-Language (HeaderNames.ContentLanguage) není uvedená v WithHeaders :
Access-Control-Request-Headers: Cache-Control, Content-Language
Aplikace vrátí odpověď 200 OK, ale neposíleje zpět hlavičky CORS. Proto se prohlížeč nepokusí o požadavek mezi zdroji.
Nastavení zveřejněných hlaviček odpovědi
Ve výchozím nastavení prohlížeč aplikaci nezpřístupňuje všechny hlavičky odpovědi. Další informace najdete v tématu Sdílení prostředků mezi zdroji W3C (terminologie): Jednoduchá hlavička odpovědi.
Hlavičky odpovědi, které jsou ve výchozím nastavení k dispozici:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
Specifikace CORS volá tyto hlavičky s jednoduchými hlavičkami odpovědi. Pokud chcete aplikaci k dispozici další hlavičky, zavolejte WithExposedHeaders :
options.AddPolicy("MyExposeResponseHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
Přihlašovací údaje v požadavcích napříč zdroji
Přihlašovací údaje vyžadují zvláštní zpracování v požadavku CORS. Ve výchozím nastavení prohlížeč neposíleje přihlašovací údaje s požadavkem mezi zdroji. Mezi přihlašovací cookie údaje patří schémata ověřování s a HTTP. Pokud chcete odeslat přihlašovací údaje s požadavkem mezi zdroji, musí klient nastavit XMLHttpRequest.withCredentials na true hodnotu .
Přímé XMLHttpRequest použití:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
Pomocí jQuery:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
Pomocí rozhraní Fetch API:
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Server musí přihlašovací údaje povolit. Pokud chcete povolit přihlašovací údaje mezi zdroji, zavolejte AllowCredentials :
options.AddPolicy("MyMyAllowCredentialsPolicy",
builder =>
{
builder.WithOrigins("http://example.com")
.AllowCredentials();
});
Odpověď HTTP obsahuje hlavičku , která prohlížeči říká, že server povoluje přihlašovací údaje pro požadavek Access-Control-Allow-Credentials mezi zdroji.
Pokud prohlížeč odešle přihlašovací údaje, ale odpověď neobsahuje platnou hlavičku, prohlížeč odpověď aplikaci nezpřístupní a požadavek napříč zdroji Access-Control-Allow-Credentials selže.
Povolení přihlašovacích údajů mezi zdroji je bezpečnostním rizikem. Web v jiné doméně může poslat přihlašovací údaje přihlášených uživatelů do aplikace jménem uživatele bez vědomí uživatele.
Specifikace CORS také uvádí, že nastavení původu na (všechny původy) je neplatné, pokud "*" je Access-Control-Allow-Credentials hlavička k dispozici.
Předběžné požadavky
U některých požadavků CORS odešle prohlížeč před vytvořením skutečného požadavku další požadavek OPTIONS. Tento požadavek se nazývá předběžná žádost. Prohlížeč může předběžné požadavky přeskočit, pokud jsou splněny všechny následující podmínky:
- Metoda požadavku je GET, HEAD nebo POST.
- Aplikace nenastaví jiné hlavičky požadavků než
Accept, , , neboAccept-LanguageContent-LanguageContent-TypeLast-Event-ID. - Pokud
Content-Typeje hlavička nastavená, má jednu z následujících hodnot:application/x-www-form-urlencodedmultipart/form-datatext/plain
Pravidlo pro hlavičky požadavku nastavené pro požadavek klienta se vztahuje na hlavičky, které aplikace nastavuje setRequestHeader voláním pro XMLHttpRequest objekt . Specifikace CORS volá tyto hlavičky author request headers. Pravidlo se nevztahuje na hlavičky, které může prohlížeč nastavit, například User-Agent Host , nebo Content-Length .
Následuje příklad odpovědi podobné předběžnému požadavku z tlačítka [Put test] v části Test CORS tohoto dokumentu.
General:
Request URL: https://cors3.azurewebsites.net/api/values/5
Request Method: OPTIONS
Status Code: 204 No Content
Response Headers:
Access-Control-Allow-Methods: PUT,DELETE,GET
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f8...8;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Vary: Origin
Request Headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Method: PUT
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0
Předběžné požadavky používají metodu HTTP OPTIONS. Může obsahovat následující hlavičky:
- Access-Control-Request-Method:Metoda HTTP, která se použije pro vlastní požadavek.
- Access-Control-Request-Headers: Seznam hlaviček požadavků, které aplikace nastavuje na skutečný požadavek. Jak jsme uvedli dříve, nezahrnuje hlavičky, které prohlížeč nastavuje, například
User-Agent. - Řízení přístupu – Povolení metod
Pokud je předběžná žádost zamítnuta, aplikace vrátí odpověď, ale nenastaví 200 OK hlavičky CORS. Proto se prohlížeč nepokusí o požadavek mezi zdroji. Příklad zamítnuté předběžné žádosti najdete v části Test CORS tohoto dokumentu.
Při použití nástrojů F12 se v aplikaci konzoly v závislosti na prohlížeči zobrazí chyba podobná jedné z následujících:
- Firefox: Blokovaný požadavek napříč zdroji: Stejná zásada původu zakáže čtení vzdáleného prostředku na adrese
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5. (Důvod: Požadavek CORS nebyl úspěšný). Další informace - Chromium na základě: Zásady CORS zablokovaly přístup k načtení ze zdroje: Odpověď na předběžnou žádost neprojde kontrolou řízení přístupu: V požadovaném prostředku není k dispozici hlavička https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 https://cors3.azurewebsites.net Access-Control-Allow-Origin. Pokud neprůhledná odpověď slouží vašim potřebám, nastavte režim požadavku na no-cors, aby se načítal prostředek se zakázaným CORS.
Pokud chcete povolit konkrétní hlavičky, volejte WithHeaders :
options.AddPolicy("MyAllowHeadersPolicy",
builder =>
{
// requires using Microsoft.Net.Http.Headers;
builder.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Pokud chcete povolit všechny hlavičky požadavku autora,zavolejte AllowAnyHeader :
options.AddPolicy("MyAllowAllHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
Prohlížeče nejsou konzistentní v tom, jak nastavují Access-Control-Request-Headers . Pokud:
- Hlavičky jsou nastavené na cokoli jiného než
"*" - AllowAnyHeader má název : Zahrnte alespoň , a a plus vlastní
AcceptContent-TypeOriginhlavičky, které chcete podporovat.
Automatický předběžné kód požadavku
Když se použijí zásady CORS:
- Globálně voláním v
app.UseCorsStartup.Configure. - Pomocí
[EnableCors]atributu .
ASP.NET Core na předběžnou žádost OPTIONS.
Povolení CORS pro každý koncový bod pomocí v současné době RequireCors nepodporuje automatické předběžné požadavky.
Toto chování je znázorněno v části Testování CORS tohoto dokumentu.
Atribut [HttpOptions] pro předběžné požadavky
Pokud je CORS povolený s příslušnou zásadou, ASP.NET Core automaticky reaguje na předběžné požadavky CORS. V některých scénářích tomu tak nemusí být. Například použití CORS se směrováním koncového bodu.
Následující kód používá atribut [HttpOptions] k vytvoření koncových bodů pro požadavky OPTIONS:
[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
// OPTIONS: api/TodoItems2/5
[HttpOptions("{id}")]
public IActionResult PreflightRoute(int id)
{
return NoContent();
}
// OPTIONS: api/TodoItems2
[HttpOptions]
public IActionResult PreflightRoute()
{
return NoContent();
}
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return BadRequest();
}
return ControllerContext.MyDisplayRouteInfo(id);
}
Pokyny k testování předchozího kódu najdete v tématu Testování CORS se směrováním koncového bodu a [HttpOptions].
Nastavení předběžného času vypršení platnosti
Access-Control-Max-AgeZáhlaví určuje, jak dlouho může být odpověď na požadavek na kontrolu před výstupem ukládána do mezipaměti. Chcete-li nastavit tuto hlavičku, zavolejte SetPreflightMaxAge :
options.AddPolicy("MySetPreflightExpirationPolicy",
builder =>
{
builder.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
Jak CORS funguje
Tato část popisuje, co se stane v žádosti CORS na úrovni zpráv HTTP.
- CORS není funkce zabezpečení. CORS je standard W3C, který umožňuje serveru zmírnit zásady stejného zdroje.
- Škodlivý objekt actor může například použít skriptování mezi weby (XSS) na vašem webu a provést požadavek napříč lokalitami na lokalitu s POVOLENým CORS, aby mohl ukrást informace.
- Rozhraní API není bezpečnější díky povolení CORS.
- Pro vymáhání CORS je to až klient (prohlížeč). Server požadavek spustí a vrátí odpověď, jedná se o klienta, který vrátí chybu a zablokuje odpověď. Například kterýkoli z následujících nástrojů zobrazí odpověď serveru:
- Fiddler
- Postman
- .NET HttpClient
- Webový prohlížeč zadáním adresy URL do panelu Adresa.
- Pro vymáhání CORS je to až klient (prohlížeč). Server požadavek spustí a vrátí odpověď, jedná se o klienta, který vrátí chybu a zablokuje odpověď. Například kterýkoli z následujících nástrojů zobrazí odpověď serveru:
- To je způsob, jak serveru dovolit prohlížečům spustit XHR nebo načíst požadavek rozhraní API pro různé zdroje, které by jinak bylo zakázané.
- Prohlížeče bez CORS nemůžou provádět žádosti mezi zdroji. Před CORS se k obcházení tohoto omezení použil JSONP . JSONP nepoužívá XHR, používá
<script>značku k přijetí odpovědi. Skripty mohou být načteny mezi zdroji.
- Prohlížeče bez CORS nemůžou provádět žádosti mezi zdroji. Před CORS se k obcházení tohoto omezení použil JSONP . JSONP nepoužívá XHR, používá
Specifikace CORS představila několik nových hlaviček protokolu HTTP, které umožňují žádosti mezi zdroji. Pokud prohlížeč podporuje CORS, nastaví tyto hlavičky pro žádosti mezi zdroji automaticky. Pro povolení CORS není nutný vlastní kód JavaScriptu.
Tlačítko Vložit test na nasazené ukázce
Následuje příklad žádosti o více zdrojů z tlačítka Test hodnot na https://cors1.azurewebsites.net/api/values . OriginHlavička:
- Poskytuje doménu lokality, ze které se vytváří požadavek.
- Je vyžadováno a musí se lišit od hostitele.
Obecné hlavičky
Request URL: https://cors1.azurewebsites.net/api/values
Request Method: GET
Status Code: 200 OK
Hlavičky odpovědi
Content-Encoding: gzip
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Powered-By: ASP.NET
Hlavičky požadavku
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: cors1.azurewebsites.net
Origin: https://cors3.azurewebsites.net
Referer: https://cors3.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 ...
V OPTIONS části požadavky Server nastaví hlavičku hlaviček odpovědi Access-Control-Allow-Origin: {allowed origin} v odpovědi. Například nasazená Ukázka, DELETE [EnableCors] OPTIONS obsahuje následující hlavičky:
Obecné hlavičky
Request URL: https://cors3.azurewebsites.net/api/TodoItems2/MyDelete2/5
Request Method: OPTIONS
Status Code: 204 No Content
Hlavičky odpovědi
Access-Control-Allow-Headers: Content-Type,x-custom-header
Access-Control-Allow-Methods: PUT,DELETE,GET,OPTIONS
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors3.azurewebsites.net
Vary: Origin
X-Powered-By: ASP.NET
Hlavičky požadavku
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: DELETE
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/test?number=2
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0
V předchozích hlavičkách odpovědi Server nastaví hlavičku Access-Control-Allow-Origin v odpovědi. https://cors1.azurewebsites.netHodnota této hlavičky se shoduje s Origin hlavičkou z požadavku.
Pokud AllowAnyOrigin je volána, Access-Control-Allow-Origin: * je vrácena hodnota zástupného znaku. AllowAnyOrigin umožňuje jakýkoli původ.
Pokud odpověď nezahrnuje Access-Control-Allow-Origin hlavičku, požadavek na více zdrojů se nezdařil. Konkrétně prohlížeč požadavek nepovoluje. I v případě, že server vrátí úspěšnou odpověď, prohlížeč nezpřístupňuje odpověď klientské aplikaci.
Zobrazit žádosti o možnosti
Ve výchozím nastavení prohlížeče Chrome a Edge nezobrazují žádosti o možnosti na kartě síť nástrojů F12. Chcete-li zobrazit žádosti o možnosti v těchto prohlížečích:
chrome://flags/#out-of-blink-corsneboedge://flags/#out-of-blink-cors- zakažte příznak.
- restart (restartovat).
Firefox ve výchozím nastavení zobrazuje požadavky na možnosti.
CORS ve službě IIS
při nasazování do služby IIS musí služba CORS běžet před ověřováním Windows, pokud server není nakonfigurovaný tak, aby povoloval anonymní přístup. Pro podporu tohoto scénáře je nutné nainstalovat a nakonfigurovat modul IIS CORS pro aplikaci.
Test CORS
Ukázka stažení obsahuje kód pro testování CORS. Viz Jak stáhnout. Ukázka je projekt rozhraní API se Razor stránkami přidanými:
public class StartupTest2
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com",
"https://cors1.azurewebsites.net",
"https://cors3.azurewebsites.net",
"https://localhost:44398",
"https://localhost:5001")
.WithMethods("PUT", "DELETE", "GET");
});
});
services.AddControllers();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
}
Upozornění
WithOrigins("https://localhost:<port>"); by se mělo používat jenom pro testování ukázkové aplikace, podobně jako u ukázkového kódu ke stažení.
Následující příklad ValuesController poskytuje koncové body pro testování:
[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public IActionResult Get() =>
ControllerContext.MyDisplayRouteInfo();
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// PUT api/values/5
[HttpPut("{id}")]
public IActionResult Put(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/values/GetValues2
[DisableCors]
[HttpGet("{action}")]
public IActionResult GetValues2() =>
ControllerContext.MyDisplayRouteInfo();
}
MyDisplayRouteInfo poskytuje balíček Rick. Docs. samples. RouteInfo NuGet a zobrazuje informace o trasách.
Otestujte předchozí vzorový kód pomocí jednoho z následujících přístupů:
- Použijte nasazenou ukázkovou aplikaci na adrese https://cors3.azurewebsites.net/ . Není nutné stahovat ukázku.
- Spusťte ukázku s
dotnet runpoužitím výchozí adresy URLhttps://localhost:5001. - spusťte ukázku z Visual Studio s portem nastaveným na 44398 pro adresu URL
https://localhost:44398.
Použití prohlížeče s nástroji F12:
Vyberte tlačítko hodnoty a zkontrolujte hlavičky na kartě síť .
Vyberte tlačítko Vložit test . Pokyny k zobrazení žádosti o možnosti najdete v tématu Možnosti zobrazení žádosti . Test Put vytvoří dvě požadavky, požadavek na kontrolu před výstupem a požadavek PUT.
Kliknutím na
GetValues2 [DisableCors]tlačítko aktivujte neúspěšnou žádost CORS. Jak je uvedeno v dokumentu, odpověď vrátí 200 úspěch, ale požadavek CORS se neprovádí. Kliknutím na kartu Konzola zobrazíte chybu CORS. V závislosti na prohlížeči se zobrazí chybová zpráva podobná následující:'https://cors1.azurewebsites.net/api/values/GetValues2''https://cors3.azurewebsites.net'Zásada CORS zablokovala přístup k načtení od původu: v požadovaném prostředku není k dispozici hlavička Access-Control-Allow-Origin. Pokud neprůhledná odpověď vyhovuje vašim potřebám, nastavte režim žádosti na No-CORS, aby bylo možné načíst prostředek s zakázáním CORS.
Koncové body s podporou CORS je možné testovat pomocí nástroje, jako je například kudrlinkou, Fiddlernebo post. Při použití nástroje se musí původ požadavku určeného Origin hlavičkou lišit od hostitele, který požadavek přijal. Pokud požadavek není mezi zdroji založen na hodnotě Origin hlavičky:
- Pro zpracování žádosti není nutné middleware CORS.
- V odpovědi nejsou vraceny hlavičky CORS.
Následující příkaz slouží curl k vystavení žádosti o možnosti s informacemi:
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
Testování CORS pomocí směrování koncových bodů a [HttpOptions]
Povolení CORS na základě jednotlivých koncových bodů pomocí v RequireCors současné době nepodporuje Automatické požadavky na kontrolu před výstupem. Vezměte v úvahu následující kód, který pomocí Směrování koncových bodů povoluje CORS:
public class StartupEndPointBugTest
{
readonly string MyPolicy = "_myPolicy";
// .WithHeaders(HeaderNames.ContentType, "x-custom-header")
// forces browsers to require a preflight request with GET
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyPolicy,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com",
"https://cors1.azurewebsites.net",
"https://cors3.azurewebsites.net",
"https://localhost:44398",
"https://localhost:5001")
.WithHeaders(HeaderNames.ContentType, "x-custom-header")
.WithMethods("PUT", "DELETE", "GET", "OPTIONS");
});
});
services.AddControllers();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireCors(MyPolicy);
endpoints.MapRazorPages();
});
}
}
Následující příklad TodoItems1Controller poskytuje koncové body pro testování:
[Route("api/[controller]")]
[ApiController]
public class TodoItems1Controller : ControllerBase
{
// PUT: api/TodoItems1/5
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return Content($"ID = {id}");
}
return ControllerContext.MyDisplayRouteInfo(id);
}
// Delete: api/TodoItems1/5
[HttpDelete("{id}")]
public IActionResult MyDelete(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/TodoItems1
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors]
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
// Delete: api/TodoItems1/MyDelete2/5
[EnableCors]
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Otestujte předchozí kód ze stránky test v nasazené ukázce.
Tlačítka DELETE [EnableCors] a Get [EnableCors] jsou úspěšná, protože koncové body mají [EnableCors] a reagují na požadavky na kontrolu před výstupem. Ostatní koncové body selžou. Tlačítko získat se nepovedlo, protože JavaScript pošle:
headers: {
"Content-Type": "x-custom-header"
},
Následující TodoItems2Controller příkaz poskytuje podobné koncové body, ale obsahuje explicitní kód pro reakci na požadavky Options:
[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
// OPTIONS: api/TodoItems2/5
[HttpOptions("{id}")]
public IActionResult PreflightRoute(int id)
{
return NoContent();
}
// OPTIONS: api/TodoItems2
[HttpOptions]
public IActionResult PreflightRoute()
{
return NoContent();
}
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return BadRequest();
}
return ControllerContext.MyDisplayRouteInfo(id);
}
// [EnableCors] // Not needed as OPTIONS path provided
[HttpDelete("{id}")]
public IActionResult MyDelete(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
[EnableCors] // Rquired for this path
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors] // Rquired for this path
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Otestujte předchozí kód ze stránky test v nasazené ukázce. V rozevíracím seznamu řadič vyberte položku Kontrola před výstupem a pak nastavte kontroler. Všechna volání CORS do TodoItems2Controller koncových bodů jsou úspěšná.