Çıkış Noktası Arası İstekleri (CORS) ASP.NET Core
Rick Anderson ve Rick Larkin
Bu makalede, bir ASP.NET Core uygulamasında CORS'nin nasıl etkinleştir ASP.NET Core açıklanmıştır.
Tarayıcı güvenliği, bir web sayfasının web sayfasına hizmet edenden farklı bir etki alanına istekte bulunarak bunu engellemesini sağlar. Bu kısıtlama, aynı çıkış noktası ilkesi olarak adlandırılan bir kısıtlamadır. Aynı çıkış noktası ilkesi, kötü amaçlı bir sitenin başka bir siteden hassas verileri okumasını önler. Bazen, diğer sitelerin uygulamanıza çıkış noktası arası istekler yapmalarına izin vermek istiyor olabilirsiniz. Daha fazla bilgi için Mozilla CORS makalesine bakın.
Çıkış Noktası Arası Kaynak Paylaşımı (CORS):
- Bir sunucunun aynı kaynak ilkeyi gevşettiklerine olanak sağlayan bir W3C standardıdır.
- Bir güvenlik özelliği değildir, CORS güvenliği gevşetir. CORS'ye izin vererek API daha güvenli değildir. Daha fazla bilgi için bkz. CORS nasıl çalışır?
- Bir sunucunun diğerlerini reddederek çıkış noktası arası isteklere açıkça izin vermesine izin verir.
- JSONP gibi önceki tekniklerden daha güvenli ve daha esnektir.
Örnek kodu görüntüleme veya indirme ( nasılindir)
Aynı kaynak
İki URL aynı şemalara, konaklara ve bağlantı noktalarına(RFC 6454)sahipse aynı çıkış noktalarına sahiptir.
Bu iki URL aynı çıkış noktasıdır:
https://example.com/foo.htmlhttps://example.com/bar.html
Bu URL'lerin çıkış noktası önceki iki URL'den farklıdır:
https://example.net: Farklı etki alanıhttps://www.example.com/foo.html: Farklı alt etki alanıhttp://example.com/foo.html: Farklı düzenhttps://example.com:9000/foo.html: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- Adlandırılmış ilke veya varsayılan ilke kullanan ara yazılımda.
- Uç nokta yönlendirmeyi kullanma.
- [EnableCors] özniteliğiyle.
[EnableCors] özniteliğini adlandırılmış bir ilkeyle kullanmak CORS'yi destekleyen uç noktaları sınırlamada en ince denetimi sağlar.
Uyarı
UseCors doğru sırayla çağrılmalı. Daha fazla bilgi için bkz. Ara yazılım sırası. Örneğin, UseCors kullanırken önce UseResponseCaching çağrılları UseResponseCaching gerekir.
Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak açıklanmıştır.
Adlandırılmış ilke ve ara yazılım ile CORS
CORS Ara Yazılımı çıkış noktası arası istekleri işler. Aşağıdaki kod, belirtilen kaynaklarla uygulamanın tüm uç noktalarına bir CORS ilkesi uygular:
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();
Yukarıdaki kod:
- İlke adını olarak
_myAllowSpecificOriginsayarlar. İlke adı rastgeledir. - Uzantı UseCors yöntemini çağırarak
_myAllowSpecificOriginsCORS ilkesi belirtir.UseCorsCORS ara yazılım ekler. çağrısınınUseCorsardından, ancak öncesindeUseRoutingyer alalır.UseAuthorizationDaha fazla bilgi için bkz. Ara yazılım sırası. - Bir AddCors lambda ifadesiyle çağrır. Lambda bir nesnesi CorsPolicyBuilder alır. gibi yapılandırmaseçenekleri
WithOriginsbu makalenin devamlarında açıklanmıştır. - Tüm denetleyici
_myAllowSpecificOriginsuç noktaları için CORS ilkesine olanak sağlar. Belirli uç noktalara CORS ilkesi uygulamak için bkz. uç nokta yönlendirme. - Response Önbelleğe Alma ara yazılımı kullanırkenönce UseCors çağrısında UseResponseCaching bulundu.
Uç nokta yönlendirme ile CORS ara yazılımı, ve çağrıları arasında yürütülecek şekilde UseRouting UseEndpoints yapılandırıldı.
Önceki koda benzer kodu test etme yönergeleri için bkz. CorS'u test etme.
Yöntem AddCors çağrısı cors hizmetlerini uygulamanın hizmet kapsayıcısı ekler:
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();
Daha fazla bilgi için bu belgede CORS ilke seçeneklerine bakın.
Yöntemler, CorsPolicyBuilder aşağıdaki kodda gösterildiği gibi zincirlenmiş olabilir:
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();
Not: Belirtilen URL,sonda eğik çizgi ( ) / içermemeli. URL ile sonlandırılırsa / karşılaştırma döndürülür ve hiçbir üst bilgi false döndürülmez.
Varsayılan ilke ve ara yazılım ile CORS
Aşağıdaki vurgulanmış kod varsayılan CORS ilkesine olanak sağlar:
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();
Yukarıdaki kod, tüm denetleyici uç noktalarına varsayılan CORS ilkesi uygular.
Uç nokta yönlendirme ile Cors'u etkinleştirme
kullanarak CORS'nin uç nokta başına temelinde RequireCors etkinleştirilmesi otomatik kontrol öncesi isteklerini desteklemez. Daha fazla bilgi için bu soruna GitHub ve [HttpOptions] ile CORS'u test edin.
Uç nokta yönlendirme ile CORS, uzantı yöntemleri kümesi kullanılarak uç nokta başına RequireCors etkinleştirilebilir:
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();
Yukarıdaki kodda:
app.UseCorsCORS ara yazılımlarını sağlar. Varsayılan ilke yapılandırılmamış olduğundan tekapp.UseCors()başına CORS'yi etkinleştirmez.- ve
/echodenetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin sağlar. - Ve
/echo2Sayfaları Razor uç noktaları, varsayılan ilke belirtilmedikten çıkış noktaları arası isteklere izin vermez.
[DisableCors] özniteliği ile uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı RequireCors bırakmaz.
Yukarıdakine benzer kodu test etme yönergeleri için bkz. Uç nokta yönlendirme ile CORS'u test etme ve [HttpOptions] .
Özniteliklerle CORS'yi etkinleştirme
[EnableCors] özniteliğiyle CORS'yi etkinleştirme ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulama en ince denetimi sağlar.
[EnableCors] özniteliği CORS'yi genel olarak uygulamaya alternatif sağlar. özniteliği, [EnableCors] tüm uç noktalar yerine seçilen uç noktalar için CORS'ye olanak sağlar:
[EnableCors]varsayılan ilkeyi belirtir.[EnableCors("{Policy String}")]adlandırılmış bir ilke belirtir.
Özniteliği [EnableCors] aşağıdakilere uygulanabilir:
- Razor Sayfası
PageModel - Denetleyici
- Denetleyici eylemi yöntemi
Denetleyicilere, sayfa modellere veya özniteliğine sahip eylem yöntemlerine farklı ilkeler [EnableCors] uygulanabilir. Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve CORS ara [EnableCors] yazılımda etkinleştirildiğinde her iki ilke de uygulanır. İlkeleri birleştirmenizi öneririz. Aynı uygulamada [EnableCors] değil özniteliğini veya ara yazılımı kullanın.
Aşağıdaki kod her yönteme farklı bir ilke uygular:
[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(),
};
}
}
Aşağıdaki kod iki CORS ilkeleri oluşturur:
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();
CORS isteklerini sınırlamak için en ince denetim için:
- Adlandırılmış
[EnableCors("MyPolicy")]bir ilke ile kullanın. - Varsayılan ilkeyi tanımlamayın.
- Uç nokta yönlendirmeyi kullanmayın.
Sonraki bölümde yer alan kod yukarıdaki listeyi karşılar.
Önceki koda benzer kodu test etme yönergeleri için bkz. CorS'u test etme.
CORS'yi devre dışı bırakma
[DisableCors] özniteliği, uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmaz.
Aşağıdaki kod CORS ilkesi "MyPolicy" tanımlar:
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();
Aşağıdaki kod eylem için CORS'yi devre dışı GetValues2 bıraktır:
[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();
}
Yukarıdaki kod:
- Uç nokta yönlendirmesi ile CORS'yi etkinleştirmez.
- Varsayılan BIR CORS ilkesitanımlamaz.
- Denetleyicinin CORS ilkesini etkinleştirmek için [Enablecors ("MyPolicy")] kullanır
"MyPolicy". - Yöntemi için CORS 'yi devre dışı bırakır
GetValues2.
Önceki kodun test edilmesine ilişkin yönergeler için bkz. Test CORS .
CORS ilke seçenekleri
Bu bölümde, bir CORS ilkesinde ayarlanmakta olabilecek çeşitli seçenekler açıklanmaktadır:
- İzin verilen kaynakları ayarla
- İzin verilen HTTP yöntemlerini ayarlama
- İzin verilen istek üst bilgilerini ayarlama
- Gösterilen yanıt üst bilgilerini ayarlama
- Kaynaklar arası isteklerde kimlik bilgileri
- Ön kontrol sona erme süresini ayarlama
AddPolicyprogram. cs' de çağrılır. Bazı seçenekler için, ilk olarak CORS 'Nin nasıl çalıştığı bölümü okumanız yararlı olabilir.
İzin verilen kaynakları ayarla
AllowAnyOrigin: Herhangi bir düzen (veya) ile tüm kaynaklardan gelen CORS isteklerine izin verir http https . AllowAnyOrigin , herhangi bir Web sitesi uygulamaya çapraz kaynak istekleri yapabildiğinden güvenli değildir.
Not
AllowAnyOriginVe AllowCredentials güvenli olmayan bir yapılandırma belirtip, siteler arası istek sahteciliği ile sonuçlanabilir. Bir uygulama her iki yöntemle yapılandırıldığında, CORS hizmeti geçersiz bir CORS yanıtı döndürür.
AllowAnyOrigin ön kontrol isteklerini ve Access-Control-Allow-Origin üstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.
SetIsOriginAllowedToAllowWildcardSubdomains: IsOriginAllowed Kaynağa izin verilip verilmediğini değerlendirirken, kaynağın yapılandırılmış bir joker karakterle eşleşmesini sağlayan bir işlev olarak ilkenin özelliğini ayarlar.
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();
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Ön kontrol isteklerini ve
Access-Control-Allow-Methodsüstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.
İzin verilen istek üst bilgilerini ayarlama
Belirli başlıkların, Yazar isteği üstbilgileriADLı bir CORS isteğinde gönderilmesine izin vermek için, ' i çağırın WithHeaders ve izin verilen üst bilgileri belirtin:
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();
Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın 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();
AllowAnyHeader ön kontrol isteklerini ve erişim-denetim-istek-üst bilgi üst bilgisini etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.
Tarafından belirtilen belirli başlıklarıyla eşleşen bir CORS ara yazılım ilkesi, WithHeaders yalnızca Access-Control-Request-Headers ' de belirtilen üstbilgiler ile tam olarak eşleşiyorsa mümkündür WithHeaders .
Örneğin, aşağıdaki gibi yapılandırılmış bir uygulamayı göz önünde bulundurun:
app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));
CORS ara yazılımı, Content-Language (headernames. contentlanguage) içinde listelenmediği için aşağıdaki istek üst bilgisi ile bir ön denetim isteğini reddettiğinde WithHeaders :
Access-Control-Request-Headers: Cache-Control, Content-Language
Uygulama 200 ok yanıtı DÖNDÜRÜYOR ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez.
Gösterilen yanıt üst bilgilerini ayarlama
Varsayılan olarak tarayıcı, tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz. W3C çıkış noktaları arası kaynak paylaşımı (terminoloji): basit yanıt üst bilgisi.
Varsayılan olarak kullanılabilen yanıt üstbilgileri şunlardır:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
CORS belirtimi, bu üst bilgiler basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulama için kullanılabilir hale getirmek için şunu çağırın 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();
Kaynaklar arası isteklerde kimlik bilgileri
Kimlik bilgileri CORS isteğinde özel işleme gerektirir. Varsayılan olarak tarayıcı, kimlik bilgilerini bir çapraz kaynak isteğiyle göndermez. Kimlik bilgileri cookie , s ve http kimlik doğrulama düzenlerini içerir. Bir çapraz kaynak isteğiyle kimlik bilgilerini göndermek için, istemcisinin olarak ayarlanması gerekir XMLHttpRequest.withCredentials true .
XMLHttpRequestDoğrudan kullanarak:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
JQuery kullanarak:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
Fetch API'sini kullanma:
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Sunucu kimlik bilgilerine izin vermelidir. Çıkış noktaları arası kimlik bilgilerine izin vermek için şunu arayın 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();
HTTP yanıtı, Access-Control-Allow-Credentials tarayıcıya sunucunun bir çapraz kaynak isteği için kimlik bilgileri verdiğini bildiren bir üst bilgi içerir.
Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli bir Access-Control-Allow-Credentials üst bilgi içermiyorsa, tarayıcı uygulamaya yanıtı kullanıma sunmaz ve çapraz kaynak isteği başarısız olur.
Çıkış noktaları arası kimlik bilgilerine izin vermek bir güvenlik riskidir. Başka bir etki alanındaki Web sitesi, kullanıcının bilgisi olmadan kullanıcı adına, oturum açmış bir kullanıcının kimlik bilgilerini uygulamaya gönderebilir.
CORS belirtimi Ayrıca "*" üst bilgi varsa, çıkış (tüm kaynaklar) ayarının geçersiz olduğunu belirtir Access-Control-Allow-Credentials .
Ön kontrol istekleri
Bazı CORS istekleri için, tarayıcı gerçek isteği yapmadan önce ek bir seçenek isteği gönderir. Bu isteğe bir ön kontrol isteğidenir. Aşağıdaki koşulların Tümü doğruysa tarayıcı, ön kontrol isteğini atlayabilir:
- İstek yöntemi al, HEAD veya POST.
- Uygulama,,, veya dışındaki istek üst bilgilerini ayarlanmamış
AcceptAccept-LanguageContent-LanguageContent-TypeLast-Event-ID. - ,
Content-TypeAyarlandıysa, aşağıdaki değerlerden birine sahip olan üst bilgi:application/x-www-form-urlencodedmultipart/form-datatext/plain
İstemci isteği için ayarlanan istek üst bilgileri kuralı, uygulamanın, nesne üzerinde çağırarak ayarladığı üst bilgiler için geçerlidir setRequestHeader XMLHttpRequest . CORS belirtimi, bu üst bilgiler Yazar istek üst bilgileriniçağırır. Kural,, veya gibi tarayıcının ayarlayabilmesi için, veya gibi bir üst bilgiye uygulanmaz User-Agent Host Content-Length .
Aşağıda, bu belgenin Test CORS bölümündeki [testi koy] düğmesinden yapılmış olan ön kontrol isteğine benzer bir yanıt verilmiştir.
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
Ön kontrol isteği http seçenekleri yöntemini kullanır. Aşağıdaki üstbilgiler bulunabilir:
- Access-Control-Request-Method: gerçek istek IÇIN kullanılacak http yöntemi.
- Erişim-denetim-istek-üstbilgiler: uygulamanın gerçek istekte ayarladığı istek üst bilgilerinin bir listesi. Daha önce belirtildiği gibi, bu, tarayıcının ayarladığı üst bilgileri içermez
User-Agent. - Erişim-denetim-Izin-Yöntemler
Ön kontrol isteği reddedilirse, uygulama bir 200 OK yanıt döndürür ancak CORS üst bilgilerini yapmaz. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez. Reddedilen bir ön kontrol isteğine bir örnek için, bu belgenin Test CORS bölümüne bakın.
Konsol uygulaması, F12 araçlarını kullanarak tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:
- Firefox: çapraz kaynak Isteği engellendi: aynı kaynak Ilkesi, konumundaki uzak kaynağı okumaktan izin vermez
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5. (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi - Chromium tabanlı: ' ' kaynağından ' ' konumundaki getirme erişimi https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 https://cors3.azurewebsites.net CORS ilkesi tarafından engellendi: ön kontrol isteğine verilen yanıt erişim denetimi denetimine geçti: istenen kaynakta ' erişim-control-Allow-origin ' üst bilgisi yok. Donuk bir yanıt ihtiyaçlarınıza hizmet veriyorsa, isteği CORS devre dışı olarak getirmek için isteğin modunu ' No-CORS ' olarak ayarlayın.
Belirli üstbilgilere izin vermek için şunu arayın 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();
Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın 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();
Tarayıcılar, nasıl ayarlandıklarından tutarlı değildir Access-Control-Request-Headers . Aşağıdakilerden biri:
- Üst bilgiler, dışında bir şeye ayarlanır
"*" - AllowAnyHeader çağrıldı: en az
Accept,Content-Type, ve, veOrigindesteklemek istediğiniz tüm özel üstbilgileri ekleyin.
Otomatik ön kontrol istek kodu
CORS ilkesi uygulandığında:
app.UseCorsProgram. cs' de çağırarak Global olarak.- Özniteliği kullanılıyor
[EnableCors].
ASP.NET Core, ön kontrol seçenekleri isteğine yanıt verir.
Şu anda bir uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleri desteklenmez.
Bu belgenin Test CORS bölümü bu davranışı gösterir.
[HttpOptions] ön kontrol istekleri için öznitelik
cors uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle cors ön denetim isteklerini otomatik olarak yanıtlar. Bazı senaryolarda bu durum olmayabilir. Örneğin, uç nokta yönlendirme Ile CORS'yi kullanma.
Aşağıdaki kod, Seçenekler istekleri için uç noktalar oluşturmak için [HttpOptions] özniteliğini kullanır:
[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);
}
Önceki kodun test edilmesine ilişkin yönergeler için bkz. Endpoint Routing Ile test CORS ve [HttpOptions] .
Ön kontrol sona erme süresini ayarlama
Access-Control-Max-AgeÜst bilgi, ön kontrol isteğine olan yanıtın ne kadar süreyle önbelleğe alınacağını belirtir. Bu üstbilgiyi ayarlamak için şunu arayın 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();
CORS nasıl kullanılır?
Bu bölümde, HTTP iletileri düzeyindeki bir CORS isteğinde ne olacağı açıklanmaktadır.
- CORS bir güvenlik özelliği değil . CORS, bir sunucunun aynı kaynaklı ilkeyi rahat bir şekilde sağlamasına izin veren bir W3C standardıdır.
- Örneğin, kötü niyetli bir aktör sitenize karşı siteler arası komut dosyası (XSS) kullanabilir ve bilgileri çalmak için CORS özellikli sitesine bir siteler arası istek yürütebilir.
- Bir API, CORS 'ye izin vererek daha güvenli değildir.
- CORS 'yi zorlamak için istemciye (tarayıcı) sahiptir. Sunucu isteği yürütür ve yanıtı döndürür. Bu, bir hatayı döndüren ve yanıtı engelleyen istemcdir. Örneğin, aşağıdaki araçlardan herhangi birinde sunucu yanıtı görüntülenir:
- Fiddler
- Postman
- .NET HttpClient
- Adres çubuğuna URL girerek bir Web tarayıcısı.
- CORS 'yi zorlamak için istemciye (tarayıcı) sahiptir. Sunucu isteği yürütür ve yanıtı döndürür. Bu, bir hatayı döndüren ve yanıtı engelleyen istemcdir. Örneğin, aşağıdaki araçlardan herhangi birinde sunucu yanıtı görüntülenir:
- Bir sunucu, tarayıcıların çapraz kaynak XHR veya Fetch API isteği çalıştırmasına izin vermesinin yasaktır bir yoludur.
- CORS içermeyen tarayıcılar, çıkış noktaları arası istekleri yapamıyor. CORS 'den önce, bu kısıtlamayı aşmak için JSONP kullanılmıştır. JSONP XHR kullanmaz,
<script>yanıtı almak için etiketini kullanır. Betiklerin, çapraz kaynak olarak yüklenmesine izin verilir.
- CORS içermeyen tarayıcılar, çıkış noktaları arası istekleri yapamıyor. CORS 'den önce, bu kısıtlamayı aşmak için JSONP kullanılmıştır. JSONP XHR kullanmaz,
CORS belirtimi , çıkış noktaları arası istekleri etkinleştiren bırkaç yeni http üst bilgisi sunmuştur. Bir tarayıcı CORS 'yi destekliyorsa, bu üst bilgileri, çıkış noktaları arası istekler için otomatik olarak ayarlar. CORS 'yi etkinleştirmek için özel JavaScript kodu gerekli değildir.
Dağıtılan örnekteki testi Yerleştir düğmesi
Aşağıda, Values test düğmesinden olan bir çapraz kaynak isteğine bir örnek verilmiştir https://cors1.azurewebsites.net/api/values . OriginÜst bilgi:
- , İsteği yapan sitenin etki alanını sağlar.
- Gereklidir ve konaktan farklı olmalıdır.
Genel üstbilgiler
Request URL: https://cors1.azurewebsites.net/api/values
Request Method: GET
Status Code: 200 OK
Yanıt üst bilgileri
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
İstek üst bilgileri
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 ...
OPTIONSİsteklerde, sunucu yanıtta yanıt üstbilgileri Access-Control-Allow-Origin: {allowed origin} üst bilgisini ayarlar. Örneğin, dağıtılan örnek, delete [enablecors] düğme OPTIONS isteği aşağıdaki üstbilgileri içerir:
Genel üstbilgiler
Request URL: https://cors3.azurewebsites.net/api/TodoItems2/MyDelete2/5
Request Method: OPTIONS
Status Code: 204 No Content
Yanıt üst bilgileri
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
İstek üst bilgileri
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
Önceki yanıt üst bilgilerinde sunucu, yanıtta Access-Control-Allow-Origin üst bilgisini ayarlar. https://cors1.azurewebsites.netBu üstbilginin değeri, Origin istekten gelen üstbilgiyle eşleşir.
AllowAnyOriginÇağrılırsa, Access-Control-Allow-Origin: * joker karakter değeri döndürülür. AllowAnyOrigin Tüm kaynağa izin verir.
Yanıt Access-Control-Allow-Origin üstbilgiyi içermiyorsa, çapraz kaynak isteği başarısız olur. Özellikle, tarayıcı isteğe izin vermez. Sunucu başarılı bir yanıt döndürse bile tarayıcı, yanıtı istemci uygulama için kullanılabilir hale getirir.
Görüntüleme SEÇENEKLERI istekleri
Varsayılan olarak, Chrome ve Edge tarayıcıları, F12 araçlarının Ağ sekmesinde seçenek isteklerini göstermez. Bu tarayıcılarda seçenek isteklerini göstermek için:
chrome://flags/#out-of-blink-corsveyaedge://flags/#out-of-blink-cors- bayrağı devre dışı bırakın.
- uygulamasını.
Firefox, varsayılan olarak seçenek isteklerini gösterir.
IIS 'de CORS
ııs 'e dağıtım yaparken, sunucu anonim erişime izin verecek şekilde yapılandırılmamışsa CORS Windows kimlik doğrulamasından önce çalışmalıdır. Bu senaryoyu desteklemek için, IIS CORS modülünün uygulama için yüklenmiş ve yapılandırılmış olması gerekir.
Test CORS
Örnek indirme , CORS 'yi test etmek için kod içerir. Bkz. indirme. Örnek, eklenen sayfaların bulunduğu bir API projem örneğidir Razor :
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();
Uyarı
WithOrigins("https://localhost:<port>"); yalnızca indirme örnek kodunabenzer bir örnek uygulamanın test edilmesi için kullanılmalıdır.
Aşağıdakiler, ValuesController test için uç noktaları sağlar:
[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();
}
mydisplayrouteınfo , Rick. Docs. Samples. routeınfo NuGet paketi tarafından sağlanır ve rota bilgilerini görüntüler.
Aşağıdaki yaklaşımlardan birini kullanarak önceki örnek kodu test edin:
- Üzerinde dağıtılan örnek uygulamayı kullanın https://cors3.azurewebsites.net/ . Örneği indirmeniz gerekmez.
dotnet runVarsayılan URL 'sini kullanarak örneği çalıştırınhttps://localhost:5001.- bir URL 'si için bağlantı noktası 44398 olarak ayarlanan Visual Studio örneği çalıştırın
https://localhost:44398.
F12 araçlarıyla bir tarayıcı kullanma:
Değerler düğmesini seçin ve ağ sekmesindeki üst bilgileri gözden geçirin.
Testi yerleştir düğmesini seçin. Seçenekler isteği görüntüleme yönergeleri için bkz. görüntüleme seçenekleri istekleri . PUT testi iki istek, bir seçenekler ön hazırlığı ISTEğI ve PUT isteği oluşturur.
GetValues2 [DisableCors]Başarısız BIR CORS isteğini tetiklemek için düğmeyi seçin. Belgede bahsedildiği gibi, yanıt 200 başarılı döndürür, ancak CORS isteği yapılmaz. CORS hatasını görmek için konsol sekmesini seçin. Tarayıcıya bağlı olarak aşağıdakine benzer bir hata görüntülenir:'https://cors1.azurewebsites.net/api/values/GetValues2'Kaynak kimden kaynağı'https://cors3.azurewebsites.net'CORS ilkesi tarafından engellendi: İstenen kaynakta ' erişim-denetim-Izin-Origin ' üst bilgisi yok. Donuk bir yanıt ihtiyaçlarınıza hizmet veriyorsa, isteği CORS devre dışı olarak getirmek için isteğin modunu ' No-CORS ' olarak ayarlayın.
CORS özellikli uç noktalar, kıvrımlı, Fiddlerveya Postmangibi bir araçla test edilebilir. Bir araç kullanırken, üst bilgi tarafından belirtilen isteğin kaynağı Origin isteği alan konaktan farklı olmalıdır. İstek, üst bilgi değerine göre Çıkış dışı değilse Origin :
- CORS ara yazılımı için isteği işleme gereksinimi yoktur.
- CORS üstbilgileri yanıtta döndürülmedi.
Aşağıdaki komut, curl bilgileri içeren BIR seçenek isteği vermek için kullanır:
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
ENDPOINT yönlendirme ve [HttpOptions] ile test CORS
Şu anda bir uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleri desteklenmez . CORS 'yi etkinleştirmek için Endpoint Routingkullanan aşağıdaki kodu göz önünde bulundurun:
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();
Aşağıdakiler TodoItems1Controller test için uç noktalar sağlar:
[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);
}
Önceki kodu dağıtılan Örneğin Test sayfasından test edin.
Bitiş noktaları, ön kontrol isteklerini içerdiğinden ve yanıt verdiği için delete [enablecors] ve Get [enablecors] düğmeleri başarılı olur [EnableCors] . Diğer uç noktalar başarısız olur. JavaScript şu şekilde gönderdiği için Al düğmesi başarısız olur:
headers: {
"Content-Type": "x-custom-header"
},
Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak seçenek isteklerine yanıt vermek için açık kod içerir:
[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);
}
Önceki kodu dağıtılan örneğin Test sayfasından test edin. Denetleyici açılan listesinde, ön kontrol ' yı ve ardından denetleyiciyi ayarla' yı seçin. Uç noktalara yönelik tüm CORS çağrıları TodoItems2Controller başarılı olur.
Ek kaynaklar
Tarafından Rick Anderson ve Kirk larkabağı
bu makalede, ASP.NET Core uygulamasında CORS 'nin nasıl etkinleştirileceği gösterilmektedir.
Tarayıcı güvenliği, bir Web sayfasının Web sayfasını sunduğundan farklı bir etki alanına istek yapmasını engeller. Bu kısıtlamaya aynı-Origin ilkesi adı verilir. Aynı-kaynak ilkesi, kötü niyetli bir sitenin gizli verileri başka bir siteden okumasını engeller. Bazen diğer sitelerin uygulamanıza çapraz çıkış istekleri yapmasına izin vermek isteyebilirsiniz. Daha fazla bilgi için bkz. MOZILLA CORS makalesi.
Çapraz kaynak kaynak paylaşımı (CORS):
- , Bir sunucunun aynı kaynak ilkeyi rahat bir şekilde sağlamasına izin veren bir W3C standardıdır.
- Güvenlik özelliği değil , CORS güvenliği. CORS 'nin izin vermesini sağlayan bir API daha güvenli değildir. Daha fazla bilgi için bkz. CORS çalışma.
- Bir sunucunun bazı çapraz kaynak isteklerine, diğerlerini reddetirken açık olarak izin almasına izin verir.
- , JSONPgibi önceki tekniklerin daha güvenli ve daha esnektir.
Örnek kodu görüntüleme veya indirme (nasıl indirileceği)
Aynı kaynak
Özdeş şemaları, konakları ve bağlantı noktalarına sahip olmaları durumunda iki URL aynı kaynağa sahiptir (RFC 6454).
Bu iki URL aynı kaynağa sahiptir:
https://example.com/foo.htmlhttps://example.com/bar.html
Bu URL 'Ler, önceki iki URL 'den farklı kaynaklardan farklıdır:
https://example.net: Farklı etki alanıhttps://www.example.com/foo.html: Farklı alt etki alanıhttp://example.com/foo.html: Farklı düzenhttps://example.com:9000/foo.html: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS 'yi etkinleştirmenin üç yolu vardır:
- Adlandırılmış bir ilke veya varsayılan ilkekullanan ara yazılımlar.
- Uç nokta yönlendirmekullanılıyor.
- [Enablecors] özniteliğiyle birlikte.
Adlandırılmış ilkeyle [Enablecors] ÖZNITELIĞINI kullanmak CORS 'yi destekleyen uç noktaları sınırlayan en yoğun denetimi sağlar.
Uyarı
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz. Ara yazılım sırası. Örneğin, kullanılmadan UseCors önce çağrılmalıdır UseResponseCaching UseResponseCaching .
Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak verilmiştir.
Adlandırılmış ilke ve ara yazılım ile CORS
CORS ara yazılımı, çıkış noktaları arası istekleri işler. Aşağıdaki kod, belirtilen kaynakları kullanarak tüm uygulamanın uç noktalarına bir CORS ilkesi uygular:
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();
});
}
}
Yukarıdaki kod:
- İlke adını olarak ayarlar
_myAllowSpecificOrigins. İlke adı rastgele olur. - UseCorsUzantı yöntemini çağırır ve
_myAllowSpecificOriginsCORS ilkesini belirtir.UseCorsCORS ara yazılımını ekler. ÇağrısınınUseCorssonraUseRouting, öncesi yerleştirilmesi gerekirUseAuthorization. Daha fazla bilgi için bkz. Ara yazılım sırası. - AddCors Lambda ifadesiile çağrılar. Lambda bir nesnesi alır CorsPolicyBuilder . Gibi yapılandırma seçenekleri,
WithOriginsBu makalenin ilerleyen kısımlarında açıklanmıştır. _myAllowSpecificOriginsTüm denetleyici uç noktaları için CORS ilkesini etkinleştirilir. Belirli uç noktalara bir CORS ilkesi uygulamak için bkz. Endpoint Routing .- yanıt Önbelleğe Alma ara yazılımıkullanırken, daha UseCors önce çağırın UseResponseCaching .
Endpoint Routing ile CORS ara yazılımı , ve çağrıları arasında yürütülecek şekilde yapılandırılmalıdır UseRouting UseEndpoints .
Yukarıdaki koda benzer test kodu hakkında yönergeler için bkz. Test CORS .
AddCorsYöntem çağrısı, uygulamanın hizmet KAPSAYıCıSıNA CORS Hizmetleri ekler:
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();
}
Daha fazla bilgi için bu belgedeki CORS ilke seçenekleri bölümüne bakın.
CorsPolicyBuilderYöntemler aşağıdaki kodda gösterildiği gibi zincirleme olabilir:
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();
}
Not: belirtilen URL sonunda eğik çizgi ( / ) içermemelidir. URL ile sonlandığında / karşılaştırma döndürülür false ve üst bilgi döndürülmez.
Varsayılan ilke ve ara yazılım ile CORS
Aşağıdaki vurgulanan kod varsayılan CORS ilkesini sunar:
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();
});
}
}
Yukarıdaki kod, tüm denetleyici uç noktalarına varsayılan CORS ilkesini uygular.
Uç nokta yönlendirme ile CORS 'yi etkinleştirme
İle uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleridesteklenmez. daha fazla bilgi için bkz. bu GitHub sorun ve Test no endpoint routing ve [HttpOptions].
Uç nokta yönlendirmesinde, CORS uzantı yöntemleri kümesi kullanılarak uç nokta temelinde etkinleştirilebilir RequireCors :
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();
});
}
}
Yukarıdaki kodda:
app.UseCorsCORS ara yazılımını sunar. Varsayılan bir ilke yapılandırılmadığından,app.UseCors()tek BAŞıNA CORS 'yi etkinleştirmeyin./echoVe denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir./echo2Razor Varsayılan ilke belirtilmediğinden ve sayfa uç noktaları, çıkış noktaları arası isteklere izin vermez .
[Disablecors] özniteliği, ile Endpoint Routing tarafından etkinleştirilen CORS 'yi devre dışı bırakmıyor RequireCors .
Yukarıdaki koda benzer test kodu hakkında yönergeler için bkz. Endpoint Routing Ile test CORS ve [HttpOptions] .
CORS 'yi özniteliklerle etkinleştir
CORS 'yi [Enablecors] özniteliğiyle etkinleştirmek ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulamak, en derin denetimi sağlar.
[Enablecors] ÖZNITELIĞI, CORS 'yi küresel olarak uygulamaya bir alternatif sağlar. [EnableCors]Öznitelik, tüm uç noktalar yerine seçili uç noktalar IÇIN CORS 'yi sunar:
[EnableCors]varsayılan ilkeyi belirtir.[EnableCors("{Policy String}")]adlandırılmış bir ilke belirtir.
[EnableCors]Özniteliği öğesine uygulanabilir:
- Razor Sayfasında
PageModel - Denetleyici
- Denetleyici eylemi yöntemi
Öznitelikleri olan denetleyicilere, sayfa modellerine veya eylem yöntemlerine farklı ilkeler uygulanabilir [EnableCors] . [EnableCors]Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve bir ara yazılım IÇINDE CORS etkinleştirildiğinde, her iki ilke de uygulanır. İlkelerin birleştirilmesi önerilir. [EnableCors] Aynı uygulamada değil, özniteliğini veya ara yazılımını kullanın.
Aşağıdaki kod her bir yönteme farklı bir ilke uygular:
[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(),
};
}
}
Aşağıdaki kod iki CORS ilkesi oluşturur:
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();
});
}
}
CORS isteklerini sınırlayan en yoğun denetim için:
[EnableCors("MyPolicy")]Adlandırılmış ilkeyle kullanın.- Varsayılan bir ilke tanımlamayın.
- Endpoint Routingkullanmayın.
Sonraki bölümdeki kod, önceki listeyi karşılar.
Yukarıdaki koda benzer test kodu hakkında yönergeler için bkz. Test CORS .
CORS 'yi devre dışı bırak
[Disablecors] özniteliği Endpoint ROUTINGtarafından etkinleştirilen CORS 'yi devre dışı bırakmıyor .
Aşağıdaki kod CORS ilkesini tanımlar "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();
});
}
}
Aşağıdaki kod, eylem için CORS 'yi devre dışı bırakır GetValues2 :
[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();
}
Yukarıdaki kod:
- , Uç nokta yönlendirmeile CORS 'yi etkinleştirmez.
- Varsayılan BIR CORS ilkesitanımlamaz.
- Denetleyicinin CORS ilkesini etkinleştirmek için [Enablecors ("MyPolicy")] kullanır
"MyPolicy". - Yöntemi için CORS 'yi devre dışı bırakır
GetValues2.
Önceki kodun test edilmesine ilişkin yönergeler için bkz. Test CORS .
CORS ilke seçenekleri
Bu bölümde, bir CORS ilkesinde ayarlanmakta olabilecek çeşitli seçenekler açıklanmaktadır:
- İzin verilen kaynakları ayarla
- İzin verilen HTTP yöntemlerini ayarlama
- İzin verilen istek üst bilgilerini ayarlama
- Gösterilen yanıt üst bilgilerini ayarlama
- Kaynaklar arası isteklerde kimlik bilgileri
- Ön kontrol sona erme süresini ayarlama
AddPolicy içinde çağırılır Startup.ConfigureServices . Bazı seçenekler için, ilk olarak CORS 'Nin nasıl çalıştığı bölümü okumanız yararlı olabilir.
İzin verilen kaynakları ayarla
AllowAnyOrigin: Herhangi bir düzen (veya) ile tüm kaynaklardan gelen CORS isteklerine izin verir http https . AllowAnyOrigin , herhangi bir Web sitesi uygulamaya çapraz kaynak istekleri yapabildiğinden güvenli değildir.
Not
AllowAnyOriginVe AllowCredentials güvenli olmayan bir yapılandırma belirtip, siteler arası istek sahteciliği ile sonuçlanabilir. Bir uygulama her iki yöntemle yapılandırıldığında, CORS hizmeti geçersiz bir CORS yanıtı döndürür.
AllowAnyOrigin ön kontrol isteklerini ve Access-Control-Allow-Origin üstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.
SetIsOriginAllowedToAllowWildcardSubdomains: IsOriginAllowed Kaynağa izin verilip verilmediğini değerlendirirken, kaynağın yapılandırılmış bir joker karakterle eşleşmesini sağlayan bir işlev olarak ilkenin özelliğini ayarlar.
options.AddPolicy("MyAllowSubdomainPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Ön kontrol isteklerini ve
Access-Control-Allow-Methodsüstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.
İzin verilen istek üst bilgilerini ayarlama
Belirli başlıkların, Yazar isteği üstbilgileriADLı bir CORS isteğinde gönderilmesine izin vermek için, ' i çağırın WithHeaders ve izin verilen üst bilgileri belirtin:
options.AddPolicy("MyAllowHeadersPolicy",
builder =>
{
// requires using Microsoft.Net.Http.Headers;
builder.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın AllowAnyHeader :
options.AddPolicy("MyAllowAllHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
AllowAnyHeader ön kontrol isteklerini ve erişim-denetim-istek-üst bilgi üst bilgisini etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.
Tarafından belirtilen belirli başlıklarıyla eşleşen bir CORS ara yazılım ilkesi, WithHeaders yalnızca Access-Control-Request-Headers ' de belirtilen üstbilgiler ile tam olarak eşleşiyorsa mümkündür WithHeaders .
Örneğin, aşağıdaki gibi yapılandırılmış bir uygulamayı göz önünde bulundurun:
app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));
CORS ara yazılımı, Content-Language (headernames. contentlanguage) içinde listelenmediği için aşağıdaki istek üst bilgisi ile bir ön denetim isteğini reddettiğinde WithHeaders :
Access-Control-Request-Headers: Cache-Control, Content-Language
Uygulama 200 ok yanıtı DÖNDÜRÜYOR ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez.
Gösterilen yanıt üst bilgilerini ayarlama
Varsayılan olarak tarayıcı, tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz. W3C çıkış noktaları arası kaynak paylaşımı (terminoloji): basit yanıt üst bilgisi.
Varsayılan olarak kullanılabilen yanıt üstbilgileri şunlardır:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
CORS belirtimi, bu üst bilgiler basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulama için kullanılabilir hale getirmek için şunu çağırın WithExposedHeaders :
options.AddPolicy("MyExposeResponseHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
Kaynaklar arası isteklerde kimlik bilgileri
Kimlik bilgileri CORS isteğinde özel işleme gerektirir. Varsayılan olarak tarayıcı, kimlik bilgilerini bir çapraz kaynak isteğiyle göndermez. Kimlik bilgileri cookie , s ve http kimlik doğrulama düzenlerini içerir. Bir çapraz kaynak isteğiyle kimlik bilgilerini göndermek için, istemcisinin olarak ayarlanması gerekir XMLHttpRequest.withCredentials true .
XMLHttpRequestDoğrudan kullanarak:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
JQuery kullanarak:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
Fetch API'sini kullanma:
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Sunucu kimlik bilgilerine izin vermelidir. Çıkış noktaları arası kimlik bilgilerine izin vermek için şunu arayın AllowCredentials :
options.AddPolicy("MyMyAllowCredentialsPolicy",
builder =>
{
builder.WithOrigins("http://example.com")
.AllowCredentials();
});
HTTP yanıtı, Access-Control-Allow-Credentials tarayıcıya sunucunun bir çapraz kaynak isteği için kimlik bilgileri verdiğini bildiren bir üst bilgi içerir.
Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli bir Access-Control-Allow-Credentials üst bilgi içermiyorsa, tarayıcı uygulamaya yanıtı kullanıma sunmaz ve çapraz kaynak isteği başarısız olur.
Çıkış noktaları arası kimlik bilgilerine izin vermek bir güvenlik riskidir. Başka bir etki alanındaki Web sitesi, kullanıcının bilgisi olmadan kullanıcı adına, oturum açmış bir kullanıcının kimlik bilgilerini uygulamaya gönderebilir.
CORS belirtimi Ayrıca "*" üst bilgi varsa, çıkış (tüm kaynaklar) ayarının geçersiz olduğunu belirtir Access-Control-Allow-Credentials .
Ön kontrol istekleri
Bazı CORS istekleri için, tarayıcı gerçek isteği yapmadan önce ek bir seçenek isteği gönderir. Bu isteğe bir ön kontrol isteğidenir. Aşağıdaki koşulların Tümü doğruysa tarayıcı, ön kontrol isteğini atlayabilir:
- İstek yöntemi al, HEAD veya POST.
- Uygulama,,, veya dışındaki istek üst bilgilerini ayarlanmamış
AcceptAccept-LanguageContent-LanguageContent-TypeLast-Event-ID. - ,
Content-TypeAyarlandıysa, aşağıdaki değerlerden birine sahip olan üst bilgi:application/x-www-form-urlencodedmultipart/form-datatext/plain
İstemci isteği için ayarlanan istek üst bilgileri kuralı, uygulamanın, nesne üzerinde çağırarak ayarladığı üst bilgiler için geçerlidir setRequestHeader XMLHttpRequest . CORS belirtimi, bu üst bilgiler Yazar istek üst bilgileriniçağırır. Kural,, veya gibi tarayıcının ayarlayabilmesi için, veya gibi bir üst bilgiye uygulanmaz User-Agent Host Content-Length .
Aşağıda, bu belgenin Test CORS bölümündeki [testi koy] düğmesinden yapılmış olan ön kontrol isteğine benzer bir yanıt verilmiştir.
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
Ön kontrol isteği http seçenekleri yöntemini kullanır. Aşağıdaki üstbilgiler bulunabilir:
- Access-Control-Request-Method: gerçek istek IÇIN kullanılacak http yöntemi.
- Erişim-denetim-istek-üstbilgiler: uygulamanın gerçek istekte ayarladığı istek üst bilgilerinin bir listesi. Daha önce belirtildiği gibi, bu, tarayıcının ayarladığı üst bilgileri içermez
User-Agent. - Erişim-denetim-Izin-Yöntemler
Ön kontrol isteği reddedilirse, uygulama bir 200 OK yanıt döndürür ancak CORS üst bilgilerini yapmaz. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez. Reddedilen bir ön kontrol isteğine bir örnek için, bu belgenin Test CORS bölümüne bakın.
Konsol uygulaması, F12 araçlarını kullanarak tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:
- Firefox: çapraz kaynak Isteği engellendi: aynı kaynak Ilkesi, konumundaki uzak kaynağı okumaktan izin vermez
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5. (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi - Chromium tabanlı: ' ' kaynağından ' ' konumundaki getirme erişimi https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 https://cors3.azurewebsites.net CORS ilkesi tarafından engellendi: ön kontrol isteğine verilen yanıt erişim denetimi denetimine geçti: istenen kaynakta ' erişim-control-Allow-origin ' üst bilgisi yok. Donuk bir yanıt ihtiyaçlarınıza hizmet veriyorsa, isteği CORS devre dışı olarak getirmek için isteğin modunu ' No-CORS ' olarak ayarlayın.
Belirli üstbilgilere izin vermek için şunu arayın WithHeaders :
options.AddPolicy("MyAllowHeadersPolicy",
builder =>
{
// requires using Microsoft.Net.Http.Headers;
builder.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın AllowAnyHeader :
options.AddPolicy("MyAllowAllHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
Tarayıcılar, nasıl ayarlandıklarından tutarlı değildir Access-Control-Request-Headers . Aşağıdakilerden biri:
- Üst bilgiler, dışında bir şeye ayarlanır
"*" - AllowAnyHeader çağrıldı: en az
Accept,Content-Type, ve, veOrigindesteklemek istediğiniz tüm özel üstbilgileri ekleyin.
Otomatik ön kontrol istek kodu
CORS ilkesi uygulandığında:
- ' İ çağırarak küresel olarak
app.UseCorsStartup.Configure. - Özniteliği kullanılıyor
[EnableCors].
ASP.NET Core, ön kontrol seçenekleri isteğine yanıt verir.
Şu anda bir uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleri desteklenmez.
Bu belgenin Test CORS bölümü bu davranışı gösterir.
[HttpOptions] ön kontrol istekleri için öznitelik
cors uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle cors ön denetim isteklerini otomatik olarak yanıtlar. Bazı senaryolarda bu durum olmayabilir. Örneğin, uç nokta yönlendirme Ile CORS'yi kullanma.
Aşağıdaki kod, Seçenekler istekleri için uç noktalar oluşturmak için [HttpOptions] özniteliğini kullanır:
[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);
}
Önceki kodun test edilmesine ilişkin yönergeler için bkz. Endpoint Routing Ile test CORS ve [HttpOptions] .
Ön kontrol sona erme süresini ayarlama
üst Access-Control-Max-Age bilgisi, kontrol öncesi isteğine yanıtın ne kadar süreyle önbelleğe alın olacağını belirtir. Bu üst bilgileri ayarlamak için çağrısında SetPreflightMaxAge arayın:
options.AddPolicy("MySetPreflightExpirationPolicy",
builder =>
{
builder.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
CORS nasıl çalışır?
Bu bölümde, BIR CORS isteğinde HTTP iletileri düzeyinde ne olduğu açık edilmektedir.
- CORS bir güvenlik özelliği değildir. CORS, bir sunucunun aynı çıkış noktası ilkesine gevşettiren bir W3C standardıdır.
- Örneğin, kötü niyetli bir aktör siteniz üzerinde Çapraz Site Betiği (XSS) kullanabilir ve bilgileri çalması için CORS etkin sitesine bir siteler arası istek yürütebilirsiniz.
- CORS'ye izin vererek API daha güvenli bir hale gelir.
- CORS'nin uygulanması istemciye (tarayıcı) göredir. Sunucu isteği yürütür ve yanıtı döndürür; hata döndüren ve yanıtı engelleyen istemcidir. Örneğin, aşağıdaki araçlardan herhangi biri sunucu yanıtını görüntüler:
- Fiddler
- Postman
- .NET HttpClient
- Adres çubuğuna URL'yi girerek bir web tarayıcısı.
- CORS'nin uygulanması istemciye (tarayıcı) göredir. Sunucu isteği yürütür ve yanıtı döndürür; hata döndüren ve yanıtı engelleyen istemcidir. Örneğin, aşağıdaki araçlardan herhangi biri sunucu yanıtını görüntüler:
- Bu, tarayıcıların çıkış noktası arası XHR veya Fetch API isteği yürütmesine izin vermek için bir sunucudur ve aksi takdirde yasaktır.
- CORS olmayan tarayıcılar çıkış noktası arası istekte kullanılamaz. CORS'den önce JSONP bu kısıtlamayı yok etmek için kullanıldı. JSONP XHR kullanmaz, yanıtı
<script>almak için etiketini kullanır. Betiklerin çıkış noktası arasında yüklenmesine izin verilir.
- CORS olmayan tarayıcılar çıkış noktası arası istekte kullanılamaz. CORS'den önce JSONP bu kısıtlamayı yok etmek için kullanıldı. JSONP XHR kullanmaz, yanıtı
CORS belirtimi, çıkış noktası arası istekleri etkinleştiren birkaç yeni HTTP üst bilgisi ortaya çıktı. Bir tarayıcı CORS'u destekliyorsa çıkış noktası arası istekler için bu üst bilgileri otomatik olarak ayarlar. CORS'yi etkinleştirmek için özel JavaScript kodu gerekli değildir.
Dağıtılan örnekte PUT test düğmesi
Aşağıda Değerler test düğmesinden 'ye çıkış noktası arası bir istek örneği ve ardından ve ve ve 2. https://cors1.azurewebsites.net/api/values Üst Origin bilgi:
- İsteği yapan sitenin etki alanını sağlar.
- Gereklidir ve konaktan farklı olması gerekir.
Genel üst bilgiler
Request URL: https://cors1.azurewebsites.net/api/values
Request Method: GET
Status Code: 200 OK
Yanıt üst bilgileri
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
İstek üst bilgileri
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 ...
OPTIONSİsteklerde, sunucu yanıtta Yanıt üst bilgileri üst Access-Control-Allow-Origin: {allowed origin} bilgilerini ayarlar. Örneğin, dağıtılan örneği , Delete [EnableCors] OPTIONS düğme isteği aşağıdaki üst bilgileri içerir:
Genel üst bilgiler
Request URL: https://cors3.azurewebsites.net/api/TodoItems2/MyDelete2/5
Request Method: OPTIONS
Status Code: 204 No Content
Yanıt üst bilgileri
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
İstek üst bilgileri
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
Yukarıdaki Yanıt üst bilgisinde, sunucu yanıtta Access-Control-Allow-Origin üst bilgilerini ayarlar. Bu https://cors1.azurewebsites.net üst bilginin değeri, istekten Origin gelen üst bilgiyle eştir.
AllowAnyOriginçağrılırsa Access-Control-Allow-Origin: * joker karakter değeri döndürülür. AllowAnyOrigin herhangi bir çıkış noktası sağlar.
Yanıtta üst bilgi yoksa Access-Control-Allow-Origin çıkış noktası arası istek başarısız olur. Tarayıcı özellikle isteği reddetti. Sunucu başarılı bir yanıt döndürse bile tarayıcı yanıtı istemci uygulamasına kullanılabilir hale getirmz.
SEÇENEKLER isteklerini görüntüleme
Varsayılan olarak Chrome ve Edge tarayıcıları F12 araçlarının ağ sekmesinde OPTIONS isteklerini göstermez. OPTIONS isteklerini bu tarayıcılarda görüntülemek için:
chrome://flags/#out-of-blink-corsveyaedge://flags/#out-of-blink-cors- bayrağını devre dışı bırak.
- Yeni -den başlatın.
Firefox varsayılan olarak OPTIONS isteklerini gösterir.
IIS'de CORS
IIS'ye dağıtırken, sunucu anonim erişime izin verecek Windows kimlik doğrulaması olmadan önce CORS'nin çalışması gerekir. Bu senaryoyu desteklemek için IIS CORS modülünün uygulama için yüklenmiş ve yapılandırılmış olması gerekir.
CORS'u test etmek
Örnek indirmede CORS'u test etmek için kod vardır. Bkz. indirme. Örnek, Sayfaların ekli olduğu bir API Razor projesidir:
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();
});
}
}
Uyarı
WithOrigins("https://localhost:<port>");yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıdakiler ValuesController test için uç noktaları sağlar:
[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, Rick.Docs.Samples.RouteInfo NuGet paketi tarafından sağlanır ve yol bilgilerini görüntüler.
Aşağıdaki yaklaşımlardan birini kullanarak önceki örnek kodu test edersiniz:
- dağıtılan örnek uygulamayı üzerinden https://cors3.azurewebsites.net/ kullanın. Örneği indirmeniz gerek yoktur.
- Varsayılan
dotnet runURL'sini kullanarak örneği ilehttps://localhost:5001çalıştırın. - url'si için bağlantı Visual Studio 44398 olarak ayarlanmış şekilde Visual Studio'den örneği
https://localhost:44398çalıştırın.
F12 araçlarıyla bir tarayıcı kullanma:
Değerler düğmesini seçin ve Ağ sekmesindeki üst bilgileri gözden geçirebilirsiniz.
PUT test düğmesini seçin. OPTIONS isteğini görüntüleme yönergeleri için bkz. SEÇENEKLER isteklerini görüntüleme. PUT testi iki istek oluşturur: OPTIONS ön kontrol isteği ve PUT isteği.
Başarısız bir
GetValues2 [DisableCors]CORS isteğini tetiklemek için düğmeyi seçin. Belgede belirtildiği gibi yanıt 200 başarı döndürür, ancak CORS isteğinde yerlanmaz. CORS hatasını görmek için Konsol sekmesini seçin. Tarayıcıya bağlı olarak aşağıdakine benzer bir hata görüntülenir:Çıkış noktası üzerinden getirme erişimi CORS ilkesi tarafından engellendi: İstenen kaynakta
'https://cors1.azurewebsites.net/api/values/GetValues2''https://cors3.azurewebsites.net''Access-Control-Allow-Origin' üst bilgisi yok. İhtiyaçlarınızı karşılarsa, CORS devre dışı bırakılmış kaynağı getirmek için isteğin modunu 'no-cors' olarak ayarlayın.
CORS özellikli uç noktalar curl , Fiddler veyaPostman gibi bir araçla test edilebilir. Bir araç kullanırken üst bilgi tarafından belirtilen isteğin kaynağı, isteği alan Origin konaktan farklı olması gerekir. İstek, üst bilginin değerine göre çıkış noktası arası Origin değilse:
- CORS Ara Yazılımı'nın isteği işlemesi gerek yoktur.
- YANıTta CORS üst bilgileri döndürülz.
Aşağıdaki komut, bir curl OPTIONS isteğinde bilgi almak için kullanır:
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
Uç nokta yönlendirme ve [HttpOptions] ile CORS'i test edin
kullanarak CORS'nin uç nokta başına temelinde RequireCors etkinleştirilmesi şu anda otomatik kontrol öncesi isteklerini desteklememektedir. CORS'yi etkinleştirmek için uç nokta yönlendirmeyi kullanan aşağıdaki kodu göz önünde bulundurabilirsiniz:
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();
});
}
}
Aşağıdakiler TodoItems1Controller test için uç noktaları sağlar:
[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);
}
Dağıtılan örneğin test sayfasından yukarıdaki kodu test edin.
Uç noktaların kontrol öncesi isteklerine sahip olması ve yanıt vermesi nedeniyle Sil [EnableCors] ve GET [EnableCors] [EnableCors] düğmeleri başarılı olur. Diğer uç noktalar başarısız olur. JavaScript şunları gönderdiği için GET düğmesi başarısız olur:
headers: {
"Content-Type": "x-custom-header"
},
Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak OPTIONS isteklerine yanıt vermek için açık kod içerir:
[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);
}
Dağıtılan örneğin test sayfasından önceki kodu test edin. Denetleyici açılan listesinde Preflight'ı ve ardından Set Controller 'ı seçin. Uç noktalara yapılan tüm CORS TodoItems2Controller çağrıları başarılı olur.