Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Note
Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Warning
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Yayımlayanlar Rick Anderson ve Kirk Larkin
Bu makalede, ASP.NET Core uygulamasında Cross-O rigin Resource Sharing'in (CORS) nasıl etkinleştirildiği gösterilmektedir.
Tarayıcı güvenliği, bir web sayfasının web sayfasına hizmet verenden farklı bir etki alanına istekte bulunmasını engeller. Bu kısıtlama aynı çıkış noktası ilkesi olarak adlandırılır. Aynı çıkış noktası ilkesi, kötü amaçlı bir sitenin başka bir siteden hassas verileri okumasını önler. Bazen başka sitelerin uygulamanıza çıkış noktaları arası isteklerde bulunmasına izin vermek isteyebilirsiniz. Daha fazla bilgi için Mozilla CORS makalesine bakın.
Çıkış Noktaları Arası Kaynak Paylaşımı (CORS):
- Bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Bir güvenlik özelliği değildir , CORS güvenliği rahatlatır. CORS'ye izin vererek API daha güvenli değildir. Daha fazla bilgi için bkz . CORS nasıl çalışır?
- Bir sunucunun bazı çıkış noktaları arası isteklere izin verirken diğerlerini reddetmesine izin verir.
- JSONP gibi önceki tekniklerden daha güvenli ve daha esnektir.
Örnek kodu görüntüleme veya indirme (indirme)
Aynı kaynak
Aynı şemalara, konaklara ve bağlantı noktalarına sahip olan iki URL'nin kaynağı aynıdır (RFC 6454).
Bu iki URL'nin kaynağı aynıdır:
https://example.com/foo.htmlhttps://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
-
https://example.net: Farklı alan adı -
https://contoso.example.com/foo.html: Farklı alt alan adı -
http://example.com/foo.html: Farklı düzen -
https://example.com:9000/foo.html: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- adlı 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ırlama konusunda en iyi denetimi sağlar.
Warning
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz. Ara katman sırası. Örneğin, UseCors kullanılırken UseResponseCachingönce UseResponseCaching çağrılmalıdır.
Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak anlatılır.
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 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,
policy =>
{
policy.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ı
_myAllowSpecificOriginsolarak ayarlar. İlke adı rastgeledir. -
UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins.UseCorsCORS ara yazılımını ekler.UseCorsçağrısı,UseRoutingsonrasına ancakUseAuthorizationöncesine yerleştirilmelidir. Daha fazla bilgi için bkz. Ara katman sırası. -
AddCors
çağırır. Lambda bir CorsPolicyBuilder nesne alır.
Yapılandırma seçenekleri, örneğin
WithOrigins, bu makalenin ilerleyen bölümlerinde açıklanmaktadır. -
_myAllowSpecificOriginsTüm denetleyici uç noktaları için CORS ilkesini etkinleştirir. Belirli uç noktalara CORS ilkesi uygulamak için bkz . uç nokta yönlendirmesi . - Yanıt önbelleğe alma ara yazılımını kullanırken, önce UseCorsöğesini çağırınUseResponseCaching.
Uç nokta yönlendirmesinde, CORS ara yazılımı, ile UseRouting çağrıları arasında çalışacak şekilde yapılandırılUseEndpoints.
Yöntem çağrısı, AddCors CORS hizmetlerini uygulamanın hizmet kapsayıcısına ekler:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.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 belgedeki CORS ilkesi seçeneklerine bakın.
Yöntemler CorsPolicyBuilder , aşağıdaki kodda gösterildiği gibi zincirlenebilir:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
policy =>
{
policy.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 sonunda eğik çizgi () içermemelidir./ URL / ile bitiyorsa, karşılaştırma false döndürür ve hiçbir başlık döndürülmez.
UseCors ve UseStaticFiles sırası
Genellikle, UseStaticFiles, UseCors'den önce çağrılır. Siteler arası statik dosyaları almak için JavaScript kullanan uygulamaların, UseCors işleminden önce UseStaticFiles çağrısını yapması gerekir.
Varsayılan ilke ve ara yazılım ile CORS
Aşağıdaki vurgulanmış kod, varsayılan CORS ilkesini etkinleştirir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.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, varsayılan CORS ilkesini tüm denetleyici uç noktalarına uygular.
Uç nokta yönlendirmesi ile Cors'i etkinleştirme
Uç nokta yönlendirme ile CORS, uzantı yöntemleri kümesi kullanılarak RequireCors uç nokta temelinde etkinleştirilebilir:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.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();
Önceki kodda:
-
app.UseCorsCORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()başına CORS'yi etkinleştirmez. -
/echove denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir. - Varsayılan bir ilke belirtilmediğinden,
/echo2ve Razor Pages uç noktaları kaynaklar arası isteklere izin vermez.
[DisableCors] özniteliği ile uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmazRequireCors.
Yukarıdakine benzer bir kodu test etme yönergeleri için bkz . CORS'yi [EnableCors] özniteliği ve RequireCors yöntemiyle test etme.
CorS'yi özniteliklerle etkinleştirme
CORS'yi [EnableCors] özniteliğiyle etkinleştirmek ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulamak en iyi denetimi sağlar.
[EnableCors] özniteliği, CORS'yi genel olarak uygulamaya bir alternatif sağlar.
[EnableCors] özniteliği, tüm uç noktalar yerine seçili uç noktalar için CORS'yi etkinleştirir:
-
[EnableCors]varsayılan ilkeyi belirtir. -
[EnableCors("{Policy String}")]adlandırılmış bir ilke belirtir.
[EnableCors] Özniteliği şu özelliklere uygulanabilir:
-
Razor Sayfa
PageModel - Controller
- Denetleyici eylem yöntemi
[EnableCors] özniteliğiyle denetleyicilere, sayfa modellerine veya eylem yöntemlerine farklı ilkeler uygulanabilir.
[EnableCors] Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve ara yazılımda CORS etkinleştirildiğinde, her iki ilke de uygulanır. İlkeleri birleştirmenizi önermiyoruz. Şunu kullanın
[EnableCors]
öznitelik veya ara yazılım, aynı uygulamada ikisi birden değil.
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 ilkesi oluşturur:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("Policy1",
policy =>
{
policy.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("AnotherPolicy",
policy =>
{
policy.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ırlamanın en iyi denetimi için:
-
[EnableCors("MyPolicy")]öğesini adlandırılmış bir ilkeyle kullanın. - Varsayılan bir ilke tanımlamayın.
- Uç nokta yönlendirme kullanmayın.
Sonraki bölümdeki kod önceki listeyi karşılar.
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 ilkesini "MyPolicy"tanımlar:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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.UseEndpoints(endpoints => {
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.Run();
Aşağıdaki kod, GetValues2 eylemi için CORS’u devre dışı bırakı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önlendirme ile CORS'yi etkinleştirmez.
- Varsayılan bir CORS ilkesi tanımlamaz.
- Denetleyici için CORS ilkesini etkinleştirmek üzere
"MyPolicy"kullanır. -
GetValues2yöntemi için CORS’u devre dışı bırakır.
Önceki kodu test etmeye ilişkin yönergeler için CORS'u Test Etme bölümüne bakın.
CORS ilke seçenekleri
Bu bölümde, CORS ilkesinde ayarlanabilecek çeşitli seçenekler açıklanmaktadır:
- İzin verilen çıkış noktalarını ayarlama
- İzin verilen HTTP yöntemlerini ayarlama
- İzin verilen istek üst bilgilerini ayarlama
- Açığa çıkarılan yanıt üst bilgilerini ayarlama
- Çapraz kaynak isteklerinde kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde Program.cs çağrılır. Bazı seçenekler için öncelikle CORS'nin çalışma şekli bölümünü okumak yararlı olabilir.
İzin verilen çıkış noktalarını ayarlama
AllowAnyOrigin: Herhangi bir şema (http veya https) ile tüm kaynaklardan GELEN CORS isteklerine izin verir.
AllowAnyOrigin güvenli değildir çünkü herhangi bir web sitesi uygulamaya çıkış noktaları arası isteklerde bulunabilir.
Warning
AllowAnyOrigin ve AllowCredentials değerlerinin belirtilmesi güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğine neden olabilir. Bir uygulama her iki yöntemle de yapılandırıldığında CORS hizmeti geçersiz bir CORS yanıtı döndürür. Ile birlikte AllowCredentials kullanarak SetIsOriginAllowed(_ => true) yerleşik denetimleri atlamak da güvenli olmayan bir yapılandırmadır.
AllowAnyOrigin, ön kontrol isteklerini ve Access-Control-Allow-Origin üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
SetIsOriginAllowedToAllowWildcardSubdomains: İlkenin IsOriginAllowed özelliğini, kaynağın izin verilip verilmediğini değerlendirirken çıkış noktalarının yapılandırılmış joker karakter etki alanıyla eşleşmesini sağlayan bir işlev olacak şekilde ayarlar.
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("https://*.example.com")
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Önceki kodda SetIsOriginAllowedToAllowWildcardSubdomains, joker kökeni "https://*.example.com" ile çağrılır. Bu yapılandırma, example.com gibi https://subdomain.example.com veya https://api.example.com alt etki alanlarından gelen CORS isteklerine izin verir.
* Joker karakterin alt etki alanı eşleştirmeyi etkinleştirmek için kaynağa eklenmesi gerekir.
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Ön kontrol isteklerini ve
Access-Control-Allow-Methodsüst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
İzin verilen istek üst bilgilerini ayarlayın
Bir CORS isteğinde yazar tanımlı istek üst bilgilerinin gönderilmesine izin vermek için WithHeaders çağrısını yapın 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,
policy =>
{
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tüm author request header'larına izin vermek için AllowAnyHeader çağrısını yapın:
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
AllowAnyHeader preflight isteklerini ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
WithHeaders tarafından belirtilen belirli üstbilgilerle eşleşen bir CORS ara yazılım ilkesi, yalnızca Access-Control-Request-Headers içinde gönderilen üstbilgiler WithHeaders içinde belirtilen üstbilgilerle tam olarak eşleştiğinde mümkündür.
Ö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) WithHeaders içinde listelenmediği için aşağıdaki istek üst bilgisine sahip bir ön kontrol isteğini reddeder:
Access-Control-Request-Headers: Cache-Control, Content-Language
Uygulama bir 204 No Content yanıt döndürür ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez.
Erişime açılan yanıt başlıklarını ayarlayın
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 üst bilgileri şunlardır:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına sunmak için WithExposedHeaders çağrısı yapın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyExposeResponseHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Kaynaklar arası isteklerde kimlik bilgileri
Kimlik bilgileri, bir CORS isteğinde özel olarak ele alınmalıdır. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri, tanımlama bilgilerini ve HTTP kimlik doğrulama şemalarını içerir. Farklı kaynaklar arası bir istekle kimlik bilgilerini göndermek için istemci, XMLHttpRequest.withCredentials değerini true olarak ayarlamalıdır.
XMLHttpRequest doğrudan kullanımı:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
jQuery kullanma:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Sunucunun kimlik bilgilerine izin vermesi gerekir. Kaynaklar arası kimlik bilgilerine izin vermek için AllowCredentials çağırın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyMyAllowCredentialsPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.AllowCredentials();
});
});
builder.Services.AddControllers();
var app = builder.Build();
HTTP yanıtı, sunucunun kaynaklar arası bir istekte kimlik bilgilerine izin verdiğini tarayıcıya bildiren bir Access-Control-Allow-Credentials üst bilgisi içerir.
Tarayıcı kimlik bilgilerini gönderir ancak yanıt geçerli bir Access-Control-Allow-Credentials başlığı içermiyorsa, tarayıcı yanıtı uygulamanın erişimine açmaz ve kaynaklar arası istek başarısız olur.
Kaynaklar arası kimlik bilgilerine izin vermek güvenlik riskidir. Başka bir etki alanındaki bir web sitesi, kullanıcının bilgisi olmadan oturum açmış bir kullanıcının kimlik bilgilerini kullanıcı adına uygulamaya gönderebilir.
CORS belirtimi ayrıca, "*" üstbilgisi mevcutsa kaynakların Access-Control-Allow-Credentials (tüm kaynaklar) olarak ayarlanmasının geçersiz olduğunu belirtir.
Ön kontrol istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, ön kontrol isteği olarak adlandırılır. Tarayıcı, aşağıdaki koşulların tümü doğruysa ön kontrol isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama,
Accept,Accept-Language,Content-Language,Content-TypeveyaLast-Event-IDdışında istek üst bilgileri ayarlamaz. -
Content-TypeÜst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencodedmultipart/form-datatext/plain
İstemci isteği için ayarlanan istek üst bilgilerine ilişkin kural, uygulamanın setRequestHeader nesnesi üzerinde XMLHttpRequest çağrısı yaparak ayarladığı üst bilgiler için geçerlidir. CORS spesifikasyonu bu üst bilgileri yazar istek üst bilgileri olarak adlandırır. Kural, tarayıcının ayarlayabileceğiniz , User-Agentveya Hostgibi Content-Lengthüst bilgiler için geçerli değildir.
Note
Bu makale, örnek kodun iki Azure web sitesine dağıtılmasıyla oluşturulan URL'leri içerir: https://cors3.azurewebsites.net ve https://cors.azurewebsites.net.
Aşağıda, bu belgenin Test CORS bölümündeki [Test et] düğmesinden yapılan denetim öncesi isteğine benzer bir örnek 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 OPTIONS yöntemini kullanır. Aşağıdaki üst bilgileri içerebilir:
- Access-Control-Request-Method: Gerçek istek için kullanılacak HTTP yöntemi.
-
Access-Control-Request-Headers: Uygulamanın gerçek istekte ayar yaptığı istek üst bilgilerinin listesi. Daha önce belirtildiği gibi, bu, tarayıcının ayardığı üst bilgileri (gibi
User-Agent) içermez.
Ön kontrol isteği reddedilirse uygulama 204 No Content yanıtı döndürür, ancak CORS başlıklarını ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilmiş bir preflight isteği örneğini görmek için bu belgedeki CORS’yi Test Et bölümüne bakın.
F12 araçlarını kullanarak, konsol uygulaması tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:
- Firefox: Çapraz Kaynak İsteği Engellendi: Aynı Kaynak İlkesi,
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5konumundaki uzak kaynağın okunmasına izin vermiyor. (Neden: CORS isteği başarılı olmadı). Daha fazla bilgi edinin - Chromium tabanlı: 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5' kaynağından 'https://cors3.azurewebsites.net' konumuna getirme erişimi CORS ilkesi tarafından engellendi: Ön kontrol isteğine verilen yanıt, erişim denetimi kontrolünden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
Belirli üstbilgilere izin vermek için WithHeaders çağrısını yapın:
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowHeadersPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tüm author request header'larına izin vermek için AllowAnyHeader çağrısını yapın:
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowAllHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tarayıcılar, Access-Control-Request-Headers öğesini nasıl ayarladıkları konusunda tutarlı değildir. Aşağıdakilerden biri varsa:
- Üstbilgiler,
"*"dışında herhangi bir değere ayarlanır -
AllowAnyHeader çağrılır: En az
Accept,Content-TypeveOriginile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik ön kontrol isteği kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
-
app.UseCorsiçindeProgram.csçağrısı yaparak genel olarak. - özniteliğini
[EnableCors]kullanma.
ASP.NET Core, denetim öncesi SEÇENEKLER isteğine yanıt verir.
Bu belgenin Test CORS bölümünde bu davranış gösterilmektedir.
Preflight istekleri için [HttpOptions] özniteliği
CORS uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle CORS denetim öncesi isteklerine otomatik olarak yanıt verir.
Aşağıdaki kod, OPTIONS 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);
}
Yukarıdaki kodu test etme yönergeleri için bkz . CORS'yi [EnableCors] özniteliği ve RequireCors yöntemiyle test etme.
Denetim öncesi süre sonu süresini ayarlama
Access-Control-Max-Age üst bilgisi, preflight isteğine verilen yanıtın ne kadar süreyle önbellekte tutulabileceğini belirtir. Bu üst bilgiyi ayarlamak için SetPreflightMaxAge çağrısını yapın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MySetPreflightExpirationPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
});
builder.Services.AddControllers();
var app = builder.Build();
Bir uç noktada CORS'yi etkinleştirme
CORS nasıl çalışır?
Bu bölüm, HTTP iletileri düzeyinde bir CORS isteğinde neler olduğunu açıklar.
- CORS bir güvenlik özelliği değildir . CORS, bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Örneğin, kötü niyetli bir aktör sitenize yönelik Siteler Arası Komut Dosyası Çalıştırma (XSS) kullanabilir ve bilgi çalmak için CORS etkinleştirilmiş kendi sitesine siteler arası bir istek gönderebilir.
- CORS'ye izin vererek API daha güvenli değildir.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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
- .NET HttpClient
- Adres çubuğuna URL'yi girerek bir web tarayıcısı.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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, bir sunucunun tarayıcıların normalde yasak olacak farklı bir origin’e yönelik XHR veya Fetch API isteği yürütmesine izin vermesinin bir yoludur.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
<script>. Betiklerin farklı kaynaklardan yüklenmesine izin verilir.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
CORS belirtimi, çıkış noktaları arası istekleri etkinleştiren birkaç yeni HTTP üst bilgisi kullanıma sunulmuştur. Tarayıcı CORS'yi destekliyorsa çıkış noktaları arası istekler için bu üst bilgileri otomatik olarak ayarlar. CORS'yi etkinleştirmek için özel JavaScript kodu gerekmez.
Aşağıda, Değerler test düğmesinden https://cors1.azurewebsites.net/api/values konumuna yapılan farklı kaynaktan gelen bir isteğin örneği verilmiştir.
Origin başlığı:
- İstekte bulunan sitenin etki alanını sağlar.
- Zorunludur ve ana bilgisayardan farklı olmalıdır.
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 isteklerinde sunucu, yanıtta Yanıt üst bilgileriAccess-Control-Allow-Origin: {allowed origin} üst bilgisini ayarlar. Örneğin, örnek kodda Delete [EnableCors] düğme OPTIONS 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 bilgilerinde, sunucu yanıttaki Access-Control-Allow-Origin üst bilgisini ayarlar.
https://cors1.azurewebsites.net Bu üst bilginin değeri istekten alınan Origin üst bilgiyle eşleşir.
AllowAnyOrigin çağrılırsa, joker karakter değeri olan Access-Control-Allow-Origin: * döndürülür.
AllowAnyOrigin herhangi bir çıkış noktası sağlar.
Yanıt Access-Control-Allow-Origin başlığını içermiyorsa, kaynaklar arası istek başarısız olur. Özellikle, tarayıcı isteğe izin vermemektedir. Sunucu başarılı bir yanıt döndürse bile, tarayıcı yanıtı istemci uygulaması için kullanılabilir hale getirmez.
HTTP'den HTTPS'ye yönlendirme, CORS ön kontrol isteğinde ERR_INVALID_REDIRECT hatasına neden olur
UseHttpsRedirection tarafından HTTPS'ye yönlendirilen, HTTP kullanan bir uç noktaya yapılan istekler ERR_INVALID_REDIRECT on the CORS preflight request ile başarısız olur.
API projeleri, istekleri HTTPS'ye yeniden yönlendirmek için kullanmak UseHttpsRedirection yerine HTTP isteklerini reddedebilir.
IIS'de CORS
IIS'ye dağıtım yaparken, sunucu anonim erişime izin verecek şekilde yapılandırılmamışsa CORS'nin Windows Kimlik Doğrulamasından önce çalışması gerekir. Bu senaryoyu desteklemek için IIS CORS modülünün uygulama için yüklenmesi ve yapılandırılması gerekir.
CORS'i test edin
Örnek indirmede CORS'yi test etmek için kod bulunur. İndirmeyi öğrenin. Örnek, Razor Pages eklenmiş bir API projesidir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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();
Warning
WithOrigins("https://localhost:<port>");yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Note
Visual Studio'da launchSettings.json kullanıyorsanız veya VS Code'da C# hata ayıklama ayarlarını yapılandırıyorsanız ve yerel olarak hata ayıklamak için IIS Express kullanıyorsanız, için IIS Express'i yapılandırdığınızdan emin olun.
"anonymousAuthentication"
false olduğunda, ASP.NET Core web ortamı ana bilgisayarı herhangi bir ön uçuş isteğini görmez. Özellikle NTLM kimlik doğrulaması ()"windowsAuthentication": true kullanıyorsanız, NTLM sınama yanıtının ilk adımı web tarayıcısına bir 401 sınaması göndermektir ve bu da denetim öncesi yolunuzun doğru yapılandırıldığını doğrulamayı zorlaştırabilir.
Aşağıdaki ValuesController, test etmek için uç noktaları sunar:
[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 yukarıdaki örnek kodu test edin:
- Örneği,
dotnet runvarsayılan URL’sini kullanarakhttps://localhost:5001ile çalıştırın. - URL’si
https://localhost:44398olan örneği, bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio’dan çalıştırın.
F12 araçlarıyla tarayıcı kullanma:
Değerler düğmesini seçin ve Ağ sekmesindeki üst bilgileri gözden geçirin.
PUT test düğmesini seçin. OPTIONS isteğinin nasıl görüntüleneceğine ilişkin yönergeler için OPTIONS isteklerini görüntüleme bölümüne bakın. PUT testi iki istek oluşturur: OPTIONS ön uçuş isteği ve PUT isteği.
GetValues2 [DisableCors]Başarısız bir CORS isteğini tetikleme düğmesini seçin. Belgede belirtildiği gibi yanıt 200 başarı 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'origin’inden'https://cors3.azurewebsites.net'konumundaki kaynağa erişim CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
CORS özellikli uç noktalar curl veya Fiddler gibi bir araçla test edilebilir. Bir araç kullanılırken, Origin üst bilgisinde belirtilen isteğin kaynağı, isteği alan ana bilgisayardan farklı olmalıdır. İstek, üst bilgisinin değerine göre Origin değilse:
- CORS ara yazılımının isteği işlemesine gerek yoktur.
- CORS başlıkları yanıtta döndürülmüyor.
Aşağıdaki komut, bilgi içeren bir OPTIONS isteği göndermek için kullanır curl :
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
CORS'yi [EnableCors] özniteliği ve RequireCors yöntemiyle test edin
uç nokta yönlendirmesini kullanarak CORS'yi her bir uç nokta için etkinleştiren RequireCors aşağıdaki kodu göz önünde bulundurun:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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.UseEndpoints(endpoints =>
{
endpoints.MapGet("/echo",
context => context.Response.WriteAsync("echo"))
.RequireCors("MyPolicy");
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.Run();
Yalnızca /echo uç noktasının, belirtilen ilkeyi kullanarak kaynaklar arası isteklere izin vermek için RequireCors kullandığına dikkat edin. Aşağıdaki denetleyiciler [EnableCors] özniteliğini kullanarak CORS'yi etkinleştirir.
Aşağıdaki TodoItems1Controller test amaçlı 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("MyPolicy")]
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
// Delete: api/TodoItems1/MyDelete2/5
[EnableCors("MyPolicy")]
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur, çünkü uç noktalarında [EnableCors] bulunur ve preflight isteklerine yanıt verirler. Diğer uç noktalar başarısız olur.
JavaScript şunları gönderdiğinden GET düğmesi başarısız oluyor:
headers: {
"Content-Type": "x-custom-header"
},
Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak SEÇENEKLER 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] // Warning ASP0023 Route '{id}' conflicts with another action route.
// An HTTP request that matches multiple routes results in an ambiguous
// match error.
[EnableCors("MyPolicy")] // Required for this path.
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors("MyPolicy")] // Required for this path.
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Yukarıdaki kod, örneği Azure'a dağıtarak test edilebilir.
Controller açılır listesinden Preflight öğesini ve ardından Denetleyiciyi Ayarla seçin. Uç noktalara yapılan TodoItems2Controller tüm CORS çağrıları başarılı olur.
Ek kaynaklar
Yayımlayanlar Rick Anderson ve Kirk Larkin
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ına hizmet verenden farklı bir etki alanına istekte bulunmasını engeller. Bu kısıtlama aynı çıkış noktası ilkesi olarak adlandırılır. Aynı çıkış noktası ilkesi, kötü amaçlı bir sitenin başka bir siteden hassas verileri okumasını önler. Bazen başka sitelerin uygulamanıza çıkış noktaları arası isteklerde bulunmasına izin vermek isteyebilirsiniz. Daha fazla bilgi için Mozilla CORS makalesine bakın.
Çıkış Noktaları Arası Kaynak Paylaşımı (CORS):
- Bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Bir güvenlik özelliği değildir , CORS güvenliği rahatlatır. CORS'ye izin vererek API daha güvenli değildir. Daha fazla bilgi için bkz . CORS nasıl çalışır?
- Bir sunucunun bazı çıkış noktaları arası isteklere izin verirken diğerlerini reddetmesine izin verir.
- JSONP gibi önceki tekniklerden daha güvenli ve daha esnektir.
Örnek kodu görüntüleme veya indirme (indirme)
Aynı kaynak
Aynı şemalara, konaklara ve bağlantı noktalarına sahip olan iki URL'nin kaynağı aynıdır (RFC 6454).
Bu iki URL'nin kaynağı aynıdır:
https://example.com/foo.htmlhttps://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
-
https://example.net: Farklı alan adı -
https://www.example.com/foo.html: Farklı alt alan adı -
http://example.com/foo.html: Farklı düzen -
https://example.com:9000/foo.html: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- adlı 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ırlama konusunda en iyi denetimi sağlar.
Warning
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz. Ara katman sırası. Örneğin, UseCors kullanılırken UseResponseCachingönce UseResponseCaching çağrılmalıdır.
Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak anlatılır.
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 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,
policy =>
{
policy.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ı
_myAllowSpecificOriginsolarak ayarlar. İlke adı rastgeledir. -
UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins.UseCorsCORS ara yazılımını ekler.UseCorsçağrısı,UseRoutingsonrasına ancakUseAuthorizationöncesine yerleştirilmelidir. Daha fazla bilgi için bkz. Ara katman sırası. -
AddCors
çağırır. Lambda bir CorsPolicyBuilder nesne alır.
Yapılandırma seçenekleri, örneğin
WithOrigins, bu makalenin ilerleyen bölümlerinde açıklanmaktadır. -
_myAllowSpecificOriginsTüm denetleyici uç noktaları için CORS ilkesini etkinleştirir. Belirli uç noktalara CORS ilkesi uygulamak için bkz . uç nokta yönlendirmesi . - Yanıt önbelleğe alma ara yazılımını kullanırken, önce UseCorsöğesini çağırınUseResponseCaching.
Uç nokta yönlendirmesinde, CORS ara yazılımı, ile UseRouting çağrıları arasında çalışacak şekilde yapılandırılUseEndpoints.
Yöntem çağrısı, AddCors CORS hizmetlerini uygulamanın hizmet kapsayıcısına ekler:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.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 belgedeki CORS ilkesi seçeneklerine bakın.
Yöntemler CorsPolicyBuilder , aşağıdaki kodda gösterildiği gibi zincirlenebilir:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
policy =>
{
policy.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 sonunda eğik çizgi () içermemelidir./ URL / ile bitiyorsa, karşılaştırma false döndürür ve hiçbir başlık döndürülmez.
Warning
UseCors, UseRouting öğesinden sonra ve UseAuthorization öğesinden önce yerleştirilmelidir. Bu, CORS üst bilgilerinin hem yetkili hem de yetkisiz çağrılar için yanıta dahil edilmesini sağlamaktır.
UseCors ve UseStaticFiles sırası
Genellikle, UseStaticFiles, UseCors'den önce çağrılır. Siteler arası statik dosyaları almak için JavaScript kullanan uygulamaların, UseCors işleminden önce UseStaticFiles çağrısını yapması gerekir.
Varsayılan ilke ve ara yazılım ile CORS
Aşağıdaki vurgulanmış kod, varsayılan CORS ilkesini etkinleştirir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.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, varsayılan CORS ilkesini tüm denetleyici uç noktalarına uygular.
Uç nokta yönlendirmesi ile Cors'i etkinleştirme
Uç nokta yönlendirme ile CORS, uzantı yöntemleri kümesi kullanılarak RequireCors uç nokta temelinde etkinleştirilebilir:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.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();
Önceki kodda:
-
app.UseCorsCORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()başına CORS'yi etkinleştirmez. -
/echove denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir. - Varsayılan bir ilke belirtilmediğinden,
/echo2ve Razor Pages uç noktaları kaynaklar arası isteklere izin vermez.
[DisableCors] özniteliği ile uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmazRequireCors.
.NET 7'de özniteliğin [EnableCors] bir parametre geçirmesi gerekir veya yoldaki belirsiz bir eşleşmeden ASP0023 Uyarısı oluşturulur. .NET 8 veya üzeri, ASP0023 uyarısını oluşturmaz.
[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] // Warning ASP0023 Route '{id}' conflicts with another action route.
// An HTTP request that matches multiple routes results in an ambiguous
// match error.
[EnableCors("MyPolicy")] // Required for this path.
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors("MyPolicy")] // Required for this path.
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Yukarıdakine benzer bir kodu test etme yönergeleri için bkz . CORS'yi [EnableCors] özniteliği ve RequireCors yöntemiyle test etme.
CorS'yi özniteliklerle etkinleştirme
CORS'yi [EnableCors] özniteliğiyle etkinleştirmek ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulamak en iyi denetimi sağlar.
[EnableCors] özniteliği, CORS'yi genel olarak uygulamaya bir alternatif sağlar.
[EnableCors] özniteliği, tüm uç noktalar yerine seçili uç noktalar için CORS'yi etkinleştirir:
-
[EnableCors]varsayılan ilkeyi belirtir. -
[EnableCors("{Policy String}")]adlandırılmış bir ilke belirtir.
[EnableCors] Özniteliği şu özelliklere uygulanabilir:
-
Razor Sayfa
PageModel - Controller
- Denetleyici eylem yöntemi
[EnableCors] özniteliğiyle denetleyicilere, sayfa modellerine veya eylem yöntemlerine farklı ilkeler uygulanabilir.
[EnableCors] Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve ara yazılımda CORS etkinleştirildiğinde, her iki ilke de uygulanır. İlkeleri birleştirmenizi önermiyoruz. Şunu kullanın
[EnableCors]
öznitelik veya ara yazılım, aynı uygulamada ikisi birden değil.
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 ilkesi oluşturur:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("Policy1",
policy =>
{
policy.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("AnotherPolicy",
policy =>
{
policy.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ırlamanın en iyi denetimi için:
-
[EnableCors("MyPolicy")]öğesini adlandırılmış bir ilkeyle kullanın. - Varsayılan bir ilke tanımlamayın.
- Uç nokta yönlendirme kullanmayın.
Sonraki bölümdeki kod önceki listeyi karşılar.
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 ilkesini "MyPolicy"tanımlar:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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.UseEndpoints(endpoints => {
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.Run();
Aşağıdaki kod, GetValues2 eylemi için CORS’u devre dışı bırakı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önlendirme ile CORS'yi etkinleştirmez.
- Varsayılan bir CORS ilkesi tanımlamaz.
- Denetleyici için CORS ilkesini etkinleştirmek üzere
"MyPolicy"kullanır. -
GetValues2yöntemi için CORS’u devre dışı bırakır.
Önceki kodu test etmeye ilişkin yönergeler için CORS'u Test Etme bölümüne bakın.
CORS ilke seçenekleri
Bu bölümde, CORS ilkesinde ayarlanabilecek çeşitli seçenekler açıklanmaktadır:
- İzin verilen çıkış noktalarını ayarlama
- İzin verilen HTTP yöntemlerini ayarlama
- İzin verilen istek üst bilgilerini ayarlama
- Açığa çıkarılan yanıt üst bilgilerini ayarlama
- Çapraz kaynak isteklerinde kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde Program.cs çağrılır. Bazı seçenekler için öncelikle CORS'nin çalışma şekli bölümünü okumak yararlı olabilir.
İzin verilen çıkış noktalarını ayarlama
AllowAnyOrigin: Herhangi bir şema (http veya https) ile tüm kaynaklardan GELEN CORS isteklerine izin verir.
AllowAnyOrigin güvenli değildir çünkü herhangi bir web sitesi uygulamaya çıkış noktaları arası isteklerde bulunabilir.
Note
AllowAnyOrigin ve AllowCredentials değerlerinin belirtilmesi güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğine neden olabilir. Bir uygulama her iki yöntemle de 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 üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
SetIsOriginAllowedToAllowWildcardSubdomains: İlkenin IsOriginAllowed özelliğini, kaynağın izin verilip verilmediğini değerlendirirken çıkış noktalarının yapılandırılmış joker karakter etki alanıyla eşleşmesini sağlayan bir işlev olacak şekilde ayarlar.
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("https://*.example.com")
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Önceki kodda SetIsOriginAllowedToAllowWildcardSubdomains, joker kökeni "https://*.example.com" ile çağrılır. Bu yapılandırma, example.com gibi https://subdomain.example.com veya https://api.example.com alt etki alanlarından gelen CORS isteklerine izin verir.
* Joker karakterin alt etki alanı eşleştirmeyi etkinleştirmek için kaynağa eklenmesi gerekir.
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Ön kontrol isteklerini ve
Access-Control-Allow-Methodsüst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
İzin verilen istek üst bilgilerini ayarlayın
Bir CORS isteğinde yazar tanımlı istek üst bilgilerinin gönderilmesine izin vermek için WithHeaders çağrısını yapın 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,
policy =>
{
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tüm author istek üst bilgilerine izin vermek için AllowAnyHeader çağırın:
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
AllowAnyHeader preflight isteklerini ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
WithHeaders tarafından belirtilen belirli üstbilgilerle eşleşen bir CORS ara yazılım ilkesi, yalnızca Access-Control-Request-Headers içinde gönderilen üstbilgiler WithHeaders içinde belirtilen üstbilgilerle tam olarak eşleştiğinde mümkündür.
Ö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) WithHeaders içinde listelenmediği için aşağıdaki istek üst bilgisine sahip bir ön kontrol isteğini reddeder:
Access-Control-Request-Headers: Cache-Control, Content-Language
Uygulama 200 Tamam yanıtı döndürür ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez.
Erişime açılan yanıt başlıklarını ayarlayın
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 üst bilgileri şunlardır:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına sunmak için WithExposedHeaders çağrısı yapın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyExposeResponseHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Kaynaklar arası isteklerde kimlik bilgileri
Kimlik bilgileri, bir CORS isteğinde özel olarak ele alınmalıdır. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri, tanımlama bilgilerini ve HTTP kimlik doğrulama şemalarını içerir. Farklı kaynaklar arası bir istekle kimlik bilgilerini göndermek için istemci, XMLHttpRequest.withCredentials değerini true olarak ayarlamalıdır.
XMLHttpRequest doğrudan kullanımı:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
jQuery kullanma:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Sunucunun kimlik bilgilerine izin vermesi gerekir. Kaynaklar arası kimlik bilgilerine izin vermek için AllowCredentials çağırın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyMyAllowCredentialsPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.AllowCredentials();
});
});
builder.Services.AddControllers();
var app = builder.Build();
HTTP yanıtı, sunucunun kaynaklar arası bir istekte kimlik bilgilerine izin verdiğini tarayıcıya bildiren bir Access-Control-Allow-Credentials üst bilgisi içerir.
Tarayıcı kimlik bilgilerini gönderir ancak yanıt geçerli bir Access-Control-Allow-Credentials başlığı içermiyorsa, tarayıcı yanıtı uygulamanın erişimine açmaz ve kaynaklar arası istek başarısız olur.
Kaynaklar arası kimlik bilgilerine izin vermek güvenlik riskidir. Başka bir etki alanındaki bir web sitesi, kullanıcının bilgisi olmadan oturum açmış bir kullanıcının kimlik bilgilerini kullanıcı adına uygulamaya gönderebilir.
CORS belirtimi ayrıca, "*" üstbilgisi mevcutsa kaynakların Access-Control-Allow-Credentials (tüm kaynaklar) olarak ayarlanmasının geçersiz olduğunu belirtir.
Ön kontrol istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, ön kontrol isteği olarak adlandırılır. Tarayıcı, aşağıdaki koşulların tümü doğruysa ön kontrol isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama,
Accept,Accept-Language,Content-Language,Content-TypeveyaLast-Event-IDdışında istek üst bilgileri ayarlamaz. -
Content-TypeÜst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencodedmultipart/form-datatext/plain
İstemci isteği için ayarlanan istek üst bilgilerine ilişkin kural, uygulamanın setRequestHeader nesnesi üzerinde XMLHttpRequest çağrısı yaparak ayarladığı üst bilgiler için geçerlidir. CORS spesifikasyonu bu üst bilgileri yazar istek üst bilgileri olarak adlandırır. Kural, tarayıcının ayarlayabileceğiniz , User-Agentveya Hostgibi Content-Lengthüst bilgiler için geçerli değildir.
Aşağıda, bu belgenin Test CORS bölümündeki [Test et] düğmesinden yapılan denetim öncesi isteğine benzer bir örnek 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 OPTIONS yöntemini kullanır. Aşağıdaki üst bilgileri içerebilir:
- Access-Control-Request-Method: Gerçek istek için kullanılacak HTTP yöntemi.
-
Access-Control-Request-Headers: Uygulamanın gerçek istekte ayar yaptığı istek üst bilgilerinin listesi. Daha önce belirtildiği gibi, bu, tarayıcının ayardığı üst bilgileri (gibi
User-Agent) içermez. - Access-Control-Allow-Methods
Ön kontrol isteği reddedilirse uygulama 200 OK yanıtı döndürür, ancak CORS başlıklarını ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilmiş bir preflight isteği örneğini görmek için bu belgedeki CORS’yi Test Et bölümüne bakın.
F12 araçlarını kullanarak, konsol uygulaması tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:
- Firefox: Çapraz Kaynak İsteği Engellendi: Aynı Kaynak İlkesi,
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5konumundaki uzak kaynağın okunmasına izin vermiyor. (Neden: CORS isteği başarılı olmadı). Daha fazla bilgi edinin - Chromium tabanlı: 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5' kaynağından 'https://cors3.azurewebsites.net' konumuna getirme erişimi CORS ilkesi tarafından engellendi: Ön kontrol isteğine verilen yanıt, erişim denetimi kontrolünden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
Belirli üstbilgilere izin vermek için WithHeaders çağrısını yapın:
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowHeadersPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tüm author istek üst bilgilerine izin vermek için AllowAnyHeader çağırın:
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowAllHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tarayıcılar, Access-Control-Request-Headers öğesini nasıl ayarladıkları konusunda tutarlı değildir. Aşağıdakilerden biri varsa:
- Üstbilgiler,
"*"dışında herhangi bir değere ayarlanır -
AllowAnyHeader çağrılır: En az
Accept,Content-TypeveOriginile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik ön kontrol isteği kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
-
app.UseCorsiçindeProgram.csçağrısı yaparak genel olarak. - özniteliğini
[EnableCors]kullanma.
ASP.NET Core, denetim öncesi SEÇENEKLER isteğine yanıt verir.
Bu belgenin Test CORS bölümünde bu davranış gösterilmektedir.
Preflight istekleri için [HttpOptions] özniteliği
CORS uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle CORS denetim öncesi isteklerine otomatik olarak yanıt verir.
Aşağıdaki kod, OPTIONS 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);
}
Yukarıdaki kodu test etme yönergeleri için bkz . CORS'yi [EnableCors] özniteliği ve RequireCors yöntemiyle test etme.
Denetim öncesi süre sonu süresini ayarlama
Access-Control-Max-Age üst bilgisi, preflight isteğine verilen yanıtın ne kadar süreyle önbellekte tutulabileceğini belirtir. Bu üst bilgiyi ayarlamak için SetPreflightMaxAge çağrısını yapın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MySetPreflightExpirationPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
});
builder.Services.AddControllers();
var app = builder.Build();
Bir uç noktada CORS'yi etkinleştirme
CORS nasıl çalışır?
Bu bölüm, HTTP iletileri düzeyinde bir CORS isteğinde neler olduğunu açıklar.
- CORS bir güvenlik özelliği değildir . CORS, bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Örneğin, kötü niyetli bir aktör sitenize yönelik Siteler Arası Komut Dosyası Çalıştırma (XSS) kullanabilir ve bilgi çalmak için CORS etkinleştirilmiş kendi sitesine siteler arası bir istek gönderebilir.
- CORS'ye izin vererek API daha güvenli değildir.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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
- .NET HttpClient
- Adres çubuğuna URL'yi girerek bir web tarayıcısı.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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, bir sunucunun tarayıcıların normalde yasak olacak farklı bir origin’e yönelik XHR veya Fetch API isteği yürütmesine izin vermesinin bir yoludur.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
<script>. Betiklerin farklı kaynaklardan yüklenmesine izin verilir.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
CORS belirtimi, çıkış noktaları arası istekleri etkinleştiren birkaç yeni HTTP üst bilgisi kullanıma sunulmuştur. Tarayıcı CORS'yi destekliyorsa çıkış noktaları arası istekler için bu üst bilgileri otomatik olarak ayarlar. CORS'yi etkinleştirmek için özel JavaScript kodu gerekmez.
Dağıtılan örnekte PUT test düğmesini seçin.
Origin başlığı:
- İstekte bulunan sitenin etki alanını sağlar.
- Zorunludur ve ana bilgisayardan farklı olmalıdır.
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 isteklerinde sunucu, yanıtta Yanıt üst bilgileriAccess-Control-Allow-Origin: {allowed origin} üst bilgisini ayarlar. Örneğin, örnek kodda Delete [EnableCors] düğme OPTIONS 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 bilgilerinde, sunucu yanıttaki Access-Control-Allow-Origin üst bilgisini ayarlar.
https://cors1.azurewebsites.net Bu üst bilginin değeri istekten alınan Origin üst bilgiyle eşleşir.
AllowAnyOrigin çağrılırsa, joker karakter değeri olan Access-Control-Allow-Origin: * döndürülür.
AllowAnyOrigin herhangi bir çıkış noktası sağlar.
Yanıt Access-Control-Allow-Origin başlığını içermiyorsa, kaynaklar arası istek başarısız olur. Özellikle, tarayıcı isteğe izin vermemektedir. Sunucu başarılı bir yanıt döndürse bile, tarayıcı yanıtı istemci uygulaması için kullanılabilir hale getirmez.
HTTP'den HTTPS'ye yönlendirme, CORS ön kontrol isteğinde ERR_INVALID_REDIRECT hatasına neden olur
UseHttpsRedirection tarafından HTTPS'ye yönlendirilen, HTTP kullanan bir uç noktaya yapılan istekler ERR_INVALID_REDIRECT on the CORS preflight request ile başarısız olur.
API projeleri, istekleri HTTPS'ye yeniden yönlendirmek için kullanmak UseHttpsRedirection yerine HTTP isteklerini reddedebilir.
IIS'de CORS
IIS'ye dağıtım yaparken, sunucu anonim erişime izin verecek şekilde yapılandırılmamışsa CORS'nin Windows Kimlik Doğrulamasından önce çalışması gerekir. Bu senaryoyu desteklemek için IIS CORS modülünün uygulama için yüklenmesi ve yapılandırılması gerekir.
CORS'i test edin
Örnek indirmede CORS'yi test etmek için kod bulunur. İndirmeyi öğrenin. Örnek, Razor Pages eklenmiş bir API projesidir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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();
Warning
WithOrigins("https://localhost:<port>");yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıdaki ValuesController, test etmek için uç noktaları sunar:
[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 yukarıdaki örnek kodu test edin:
- Örneği,
dotnet runvarsayılan URL’sini kullanarakhttps://localhost:5001ile çalıştırın. - URL’si
https://localhost:44398olan örneği, bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio’dan çalıştırın.
F12 araçlarıyla tarayıcı kullanma:
Değerler düğmesini seçin ve Ağ sekmesindeki üst bilgileri gözden geçirin.
PUT test düğmesini seçin. OPTIONS isteğinin nasıl görüntüleneceğine ilişkin yönergeler için OPTIONS isteklerini görüntüleme bölümüne bakın. PUT testi iki istek oluşturur: OPTIONS ön uçuş isteği ve PUT isteği.
GetValues2 [DisableCors]Başarısız bir CORS isteğini tetikleme düğmesini seçin. Belgede belirtildiği gibi yanıt 200 başarı 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'origin’inden'https://cors3.azurewebsites.net'konumundaki kaynağa erişim CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
CORS özellikli uç noktalar curl veya Fiddler gibi bir araçla test edilebilir. Bir araç kullanılırken, Origin üst bilgisinde belirtilen isteğin kaynağı, isteği alan ana bilgisayardan farklı olmalıdır. İstek, üst bilgisinin değerine göre Origin değilse:
- CORS ara yazılımının isteği işlemesine gerek yoktur.
- CORS başlıkları yanıtta döndürülmüyor.
Aşağıdaki komut, bilgi içeren bir OPTIONS isteği göndermek için kullanır curl :
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
CORS'yi [EnableCors] özniteliği ve RequireCors yöntemiyle test edin
uç nokta yönlendirmesini kullanarak CORS'yi her bir uç nokta için etkinleştiren RequireCors aşağıdaki kodu göz önünde bulundurun:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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.UseEndpoints(endpoints =>
{
endpoints.MapGet("/echo",
context => context.Response.WriteAsync("echo"))
.RequireCors("MyPolicy");
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.Run();
Yalnızca /echo uç noktasının, belirtilen ilkeyi kullanarak kaynaklar arası isteklere izin vermek için RequireCors kullandığına dikkat edin. Aşağıdaki denetleyiciler [EnableCors] özniteliğini kullanarak CORS'yi etkinleştirir.
Aşağıdaki TodoItems1Controller test amaçlı 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("MyPolicy")]
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
// Delete: api/TodoItems1/MyDelete2/5
[EnableCors("MyPolicy")]
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur, çünkü uç noktalarında [EnableCors] bulunur ve preflight isteklerine yanıt verirler. Diğer uç noktalar başarısız olur.
JavaScript şunları gönderdiğinden GET düğmesi başarısız oluyor:
headers: {
"Content-Type": "x-custom-header"
},
Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak SEÇENEKLER 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] // Warning ASP0023 Route '{id}' conflicts with another action route.
// An HTTP request that matches multiple routes results in an ambiguous
// match error.
[EnableCors("MyPolicy")] // Required for this path.
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors("MyPolicy")] // Required for this path.
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Yukarıdaki kod, örneği Azure'da dağıtarak test edilebilir. Denetleyici açılır listesinde Preflight'ı ve ardından Denetleyiciyi Ayarla'yı seçin. Uç noktalara yapılan TodoItems2Controller tüm CORS çağrıları başarılı olur.
Ek kaynaklar
Yayımlayanlar Rick Anderson ve Kirk Larkin
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ına hizmet verenden farklı bir etki alanına istekte bulunmasını engeller. Bu kısıtlama aynı çıkış noktası ilkesi olarak adlandırılır. Aynı çıkış noktası ilkesi, kötü amaçlı bir sitenin başka bir siteden hassas verileri okumasını önler. Bazen başka sitelerin uygulamanıza çıkış noktaları arası isteklerde bulunmasına izin vermek isteyebilirsiniz. Daha fazla bilgi için Mozilla CORS makalesine bakın.
Çıkış Noktaları Arası Kaynak Paylaşımı (CORS):
- Bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Bir güvenlik özelliği değildir , CORS güvenliği rahatlatır. CORS'ye izin vererek API daha güvenli değildir. Daha fazla bilgi için bkz . CORS nasıl çalışır?
- Bir sunucunun bazı çıkış noktaları arası isteklere izin verirken diğerlerini reddetmesine izin verir.
- JSONP gibi önceki tekniklerden daha güvenli ve daha esnektir.
Örnek kodu görüntüleme veya indirme (indirme)
Aynı kaynak
Aynı şemalara, konaklara ve bağlantı noktalarına sahip olan iki URL'nin kaynağı aynıdır (RFC 6454).
Bu iki URL'nin kaynağı aynıdır:
https://example.com/foo.htmlhttps://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
-
https://example.net: Farklı alan adı -
https://www.example.com/foo.html: Farklı alt alan adı -
http://example.com/foo.html: Farklı düzen -
https://example.com:9000/foo.html: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- adlı 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ırlama konusunda en iyi denetimi sağlar.
Warning
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz. Ara katman sırası. Örneğin, UseCors kullanılırken UseResponseCachingönce UseResponseCaching çağrılmalıdır.
Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak anlatılır.
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 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,
policy =>
{
policy.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ı
_myAllowSpecificOriginsolarak ayarlar. İlke adı rastgeledir. -
UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins.UseCorsCORS ara yazılımını ekler.UseCorsçağrısı,UseRoutingsonrasına ancakUseAuthorizationöncesine yerleştirilmelidir. Daha fazla bilgi için bkz. Ara katman sırası. -
AddCors
çağırır. Lambda bir CorsPolicyBuilder nesne alır.
Yapılandırma seçenekleri, örneğin
WithOrigins, bu makalenin ilerleyen bölümlerinde açıklanmaktadır. -
_myAllowSpecificOriginsTüm denetleyici uç noktaları için CORS ilkesini etkinleştirir. Belirli uç noktalara CORS ilkesi uygulamak için bkz . uç nokta yönlendirmesi . - Yanıt önbelleğe alma ara yazılımını kullanırken, önce UseCorsöğesini çağırınUseResponseCaching.
Uç nokta yönlendirmesinde, CORS ara yazılımı, ile UseRouting çağrıları arasında çalışacak şekilde yapılandırılUseEndpoints.
Yöntem çağrısı, AddCors CORS hizmetlerini uygulamanın hizmet kapsayıcısına ekler:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.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 belgedeki CORS ilkesi seçeneklerine bakın.
Yöntemler CorsPolicyBuilder , aşağıdaki kodda gösterildiği gibi zincirlenebilir:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
policy =>
{
policy.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 sonunda eğik çizgi () içermemelidir./ URL / ile bitiyorsa, karşılaştırma false döndürür ve hiçbir başlık döndürülmez.
Warning
UseCors, UseRouting öğesinden sonra ve UseAuthorization öğesinden önce yerleştirilmelidir. Bu, CORS üst bilgilerinin hem yetkili hem de yetkisiz çağrılar için yanıta dahil edilmesini sağlamaktır.
UseCors ve UseStaticFiles sırası
Genellikle, UseStaticFiles, UseCors'den önce çağrılır. Siteler arası statik dosyaları almak için JavaScript kullanan uygulamaların, UseCors işleminden önce UseStaticFiles çağrısını yapması gerekir.
Varsayılan ilke ve ara yazılım ile CORS
Aşağıdaki vurgulanmış kod, varsayılan CORS ilkesini etkinleştirir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.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, varsayılan CORS ilkesini tüm denetleyici uç noktalarına uygular.
Uç nokta yönlendirmesi ile Cors'i etkinleştirme
kullanarak RequireCorsCORS'nin uç nokta başına etkinleştirilmesi otomatik denetim öncesi istekleri desteklemez. Daha fazla bilgi için bu GitHub sorununa bakın ve CORS'yi uç nokta yönlendirme ve [HttpOptions] ile test edin.
Uç nokta yönlendirme ile CORS, uzantı yöntemleri kümesi kullanılarak RequireCors uç nokta temelinde etkinleştirilebilir:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.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();
Önceki kodda:
-
app.UseCorsCORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()başına CORS'yi etkinleştirmez. -
/echove denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir. - Varsayılan bir ilke belirtilmediğinden,
/echo2ve Razor Pages uç noktaları kaynaklar arası isteklere izin vermez.
[DisableCors] özniteliği ile uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmazRequireCors.
Yukarıdakine benzer bir kodu test etme yönergeleri için bkz . Uç nokta yönlendirme ve [HttpOptions] ile CORS'yi test etme.
CorS'yi özniteliklerle etkinleştirme
CORS'yi [EnableCors] özniteliğiyle etkinleştirmek ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulamak en iyi denetimi sağlar.
[EnableCors] özniteliği, CORS'yi genel olarak uygulamaya bir alternatif sağlar.
[EnableCors] özniteliği, tüm uç noktalar yerine seçili uç noktalar için CORS'yi etkinleştirir:
-
[EnableCors]varsayılan ilkeyi belirtir. -
[EnableCors("{Policy String}")]adlandırılmış bir ilke belirtir.
[EnableCors] Özniteliği şu özelliklere uygulanabilir:
-
Razor Sayfa
PageModel - Controller
- Denetleyici eylem yöntemi
[EnableCors] özniteliğiyle denetleyicilere, sayfa modellerine veya eylem yöntemlerine farklı ilkeler uygulanabilir.
[EnableCors] Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve ara yazılımda CORS etkinleştirildiğinde, her iki ilke de uygulanır. İlkeleri birleştirmenizi önermiyoruz. Şunu kullanın
[EnableCors]
öznitelik veya ara yazılım, aynı uygulamada ikisi birden değil.
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 ilkesi oluşturur:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("Policy1",
policy =>
{
policy.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("AnotherPolicy",
policy =>
{
policy.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ırlamanın en iyi denetimi için:
-
[EnableCors("MyPolicy")]öğesini adlandırılmış bir ilkeyle kullanın. - Varsayılan bir ilke tanımlamayın.
- Uç nokta yönlendirme kullanmayın.
Sonraki bölümdeki kod önceki listeyi karşılar.
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 ilkesini "MyPolicy"tanımlar:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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, GetValues2 eylemi için CORS’u devre dışı bırakı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önlendirme ile CORS'yi etkinleştirmez.
- Varsayılan bir CORS ilkesi tanımlamaz.
- Denetleyici için CORS ilkesini etkinleştirmek üzere
"MyPolicy"kullanır. -
GetValues2yöntemi için CORS’u devre dışı bırakır.
Önceki kodu test etmeye ilişkin yönergeler için CORS'u Test Etme bölümüne bakın.
CORS ilke seçenekleri
Bu bölümde, CORS ilkesinde ayarlanabilecek çeşitli seçenekler açıklanmaktadır:
- İzin verilen çıkış noktalarını ayarlama
- İzin verilen HTTP yöntemlerini ayarlama
- İzin verilen istek üst bilgilerini ayarlama
- Açığa çıkarılan yanıt üst bilgilerini ayarlama
- Çapraz kaynak isteklerinde kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde Program.cs çağrılır. Bazı seçenekler için öncelikle CORS'nin çalışma şekli bölümünü okumak yararlı olabilir.
İzin verilen çıkış noktalarını ayarlama
AllowAnyOrigin: Herhangi bir şema (http veya https) ile tüm kaynaklardan GELEN CORS isteklerine izin verir.
AllowAnyOrigin güvenli değildir çünkü herhangi bir web sitesi uygulamaya çıkış noktaları arası isteklerde bulunabilir.
Note
AllowAnyOrigin ve AllowCredentials değerlerinin belirtilmesi güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğine neden olabilir. Bir uygulama her iki yöntemle de 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 üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
SetIsOriginAllowedToAllowWildcardSubdomains: İlkenin IsOriginAllowed özelliğini, kaynağın izin verilip verilmediğini değerlendirirken çıkış noktalarının yapılandırılmış joker karakter etki alanıyla eşleşmesini sağlayan bir işlev olacak şekilde ayarlar.
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("https://*.example.com")
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Önceki kodda SetIsOriginAllowedToAllowWildcardSubdomains, joker kökeni "https://*.example.com" ile çağrılır. Bu yapılandırma, example.com gibi https://subdomain.example.com veya https://api.example.com alt etki alanlarından gelen CORS isteklerine izin verir.
* Joker karakterin alt etki alanı eşleştirmeyi etkinleştirmek için kaynağa eklenmesi gerekir.
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Ön kontrol isteklerini ve
Access-Control-Allow-Methodsüst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
İzin verilen istek üst bilgilerini ayarlayın
Bir CORS isteğinde yazar tanımlı istek üst bilgilerinin gönderilmesine izin vermek için WithHeaders çağrısını yapın 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,
policy =>
{
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tüm author istek üst bilgilerine izin vermek için AllowAnyHeader çağırın:
var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
AllowAnyHeader preflight isteklerini ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
WithHeaders tarafından belirtilen belirli üstbilgilerle eşleşen bir CORS ara yazılım ilkesi, yalnızca Access-Control-Request-Headers içinde gönderilen üstbilgiler WithHeaders içinde belirtilen üstbilgilerle tam olarak eşleştiğinde mümkündür.
Ö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) WithHeaders içinde listelenmediği için aşağıdaki istek üst bilgisine sahip bir ön kontrol isteğini reddeder:
Access-Control-Request-Headers: Cache-Control, Content-Language
Uygulama 200 Tamam yanıtı döndürür ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez.
Erişime açılan yanıt başlıklarını ayarlayın
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 üst bilgileri şunlardır:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına sunmak için WithExposedHeaders çağrısı yapın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyExposeResponseHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Kaynaklar arası isteklerde kimlik bilgileri
Kimlik bilgileri, bir CORS isteğinde özel olarak ele alınmalıdır. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri, tanımlama bilgilerini ve HTTP kimlik doğrulama şemalarını içerir. Farklı kaynaklar arası bir istekle kimlik bilgilerini göndermek için istemci, XMLHttpRequest.withCredentials değerini true olarak ayarlamalıdır.
XMLHttpRequest doğrudan kullanımı:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
jQuery kullanma:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Sunucunun kimlik bilgilerine izin vermesi gerekir. Kaynaklar arası kimlik bilgilerine izin vermek için AllowCredentials çağırın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyMyAllowCredentialsPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.AllowCredentials();
});
});
builder.Services.AddControllers();
var app = builder.Build();
HTTP yanıtı, sunucunun kaynaklar arası bir istekte kimlik bilgilerine izin verdiğini tarayıcıya bildiren bir Access-Control-Allow-Credentials üst bilgisi içerir.
Tarayıcı kimlik bilgilerini gönderir ancak yanıt geçerli bir Access-Control-Allow-Credentials başlığı içermiyorsa, tarayıcı yanıtı uygulamanın erişimine açmaz ve kaynaklar arası istek başarısız olur.
Kaynaklar arası kimlik bilgilerine izin vermek güvenlik riskidir. Başka bir etki alanındaki bir web sitesi, kullanıcının bilgisi olmadan oturum açmış bir kullanıcının kimlik bilgilerini kullanıcı adına uygulamaya gönderebilir.
CORS belirtimi ayrıca, "*" üstbilgisi mevcutsa kaynakların Access-Control-Allow-Credentials (tüm kaynaklar) olarak ayarlanmasının geçersiz olduğunu belirtir.
Ön kontrol istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, ön kontrol isteği olarak adlandırılır. Tarayıcı, aşağıdaki koşulların tümü doğruysa ön kontrol isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama,
Accept,Accept-Language,Content-Language,Content-TypeveyaLast-Event-IDdışında istek üst bilgileri ayarlamaz. -
Content-TypeÜst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencodedmultipart/form-datatext/plain
İstemci isteği için ayarlanan istek üst bilgilerine ilişkin kural, uygulamanın setRequestHeader nesnesi üzerinde XMLHttpRequest çağrısı yaparak ayarladığı üst bilgiler için geçerlidir. CORS spesifikasyonu bu üst bilgileri yazar istek üst bilgileri olarak adlandırır. Kural, tarayıcının ayarlayabileceğiniz , User-Agentveya Hostgibi Content-Lengthüst bilgiler için geçerli değildir.
Aşağıda, bu belgenin Test CORS bölümündeki [Test et] düğmesinden yapılan denetim öncesi isteğine benzer bir örnek 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 OPTIONS yöntemini kullanır. Aşağıdaki üst bilgileri içerebilir:
- Access-Control-Request-Method: Gerçek istek için kullanılacak HTTP yöntemi.
-
Access-Control-Request-Headers: Uygulamanın gerçek istekte ayar yaptığı istek üst bilgilerinin listesi. Daha önce belirtildiği gibi, bu, tarayıcının ayardığı üst bilgileri (gibi
User-Agent) içermez. - Access-Control-Allow-Methods
Ön kontrol isteği reddedilirse uygulama 200 OK yanıtı döndürür, ancak CORS başlıklarını ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilmiş bir preflight isteği örneğini görmek için bu belgedeki CORS’yi Test Et bölümüne bakın.
F12 araçlarını kullanarak, konsol uygulaması tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:
- Firefox: Çapraz Kaynak İsteği Engellendi: Aynı Kaynak İlkesi,
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5konumundaki uzak kaynağın okunmasına izin vermiyor. (Neden: CORS isteği başarılı olmadı). Daha fazla bilgi edinin - Chromium tabanlı: 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5' kaynağından 'https://cors3.azurewebsites.net' konumuna getirme erişimi CORS ilkesi tarafından engellendi: Ön kontrol isteğine verilen yanıt, erişim denetimi kontrolünden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
Belirli üstbilgilere izin vermek için WithHeaders çağrısını yapın:
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowHeadersPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tüm author istek üst bilgilerine izin vermek için AllowAnyHeader çağırın:
using Microsoft.Net.Http.Headers;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyAllowAllHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
Tarayıcılar, Access-Control-Request-Headers öğesini nasıl ayarladıkları konusunda tutarlı değildir. Aşağıdakilerden biri varsa:
- Üstbilgiler,
"*"dışında herhangi bir değere ayarlanır -
AllowAnyHeader çağrılır: En az
Accept,Content-TypeveOriginile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik ön kontrol isteği kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
-
app.UseCorsiçindeProgram.csçağrısı yaparak genel olarak. - özniteliğini
[EnableCors]kullanma.
ASP.NET Core, denetim öncesi SEÇENEKLER isteğine yanıt verir.
RequireCors kullanılarak CORS'nin uç nokta bazında etkinleştirilmesi şu anda otomatik ön kontrol isteklerini desteklemez.
Bu belgenin Test CORS bölümünde bu davranış gösterilmektedir.
Preflight istekleri için [HttpOptions] özniteliği
CORS uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle CORS denetim öncesi isteklerine otomatik olarak yanıt verir. Bazı senaryolarda bu durum söz konusu olmayabilir. Örneğin, uç nokta yönlendirme ile CORS kullanma.
Aşağıdaki kod, OPTIONS 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);
}
Yukarıdaki kodu test etme yönergeleri için Uç nokta yönlendirmesi ve [HttpOptions] ile CORS'yi test etme bölümüne bkz.
Denetim öncesi süre sonu süresini ayarlama
Access-Control-Max-Age üst bilgisi, preflight isteğine verilen yanıtın ne kadar süreyle önbellekte tutulabileceğini belirtir. Bu üst bilgiyi ayarlamak için SetPreflightMaxAge çağrısını yapın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("MySetPreflightExpirationPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
});
builder.Services.AddControllers();
var app = builder.Build();
CORS nasıl çalışır?
Bu bölüm, HTTP iletileri düzeyinde bir CORS isteğinde neler olduğunu açıklar.
- CORS bir güvenlik özelliği değildir . CORS, bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Örneğin, kötü niyetli bir aktör sitenize yönelik Siteler Arası Komut Dosyası Çalıştırma (XSS) kullanabilir ve bilgi çalmak için CORS etkinleştirilmiş kendi sitesine siteler arası bir istek gönderebilir.
- CORS'ye izin vererek API daha güvenli değildir.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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
- .NET HttpClient
- Adres çubuğuna URL'yi girerek bir web tarayıcısı.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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, bir sunucunun tarayıcıların normalde yasak olacak farklı bir origin’e yönelik XHR veya Fetch API isteği yürütmesine izin vermesinin bir yoludur.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
<script>. Betiklerin farklı kaynaklardan yüklenmesine izin verilir.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
CORS belirtimi, çıkış noktaları arası istekleri etkinleştiren birkaç yeni HTTP üst bilgisi kullanıma sunulmuştur. Tarayıcı CORS'yi destekliyorsa çıkış noktaları arası istekler için bu üst bilgileri otomatik olarak ayarlar. CORS'yi etkinleştirmek için özel JavaScript kodu gerekmez.
Aşağıda, Değerler test düğmesinden https://cors1.azurewebsites.net/api/values konumuna yapılan farklı kaynaktan gelen bir isteğin örneği verilmiştir.
Origin başlığı:
- İstekte bulunan sitenin etki alanını sağlar.
- Zorunludur ve ana bilgisayardan farklı olmalıdır.
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 isteklerinde sunucu, yanıtta Yanıt üst bilgileriAccess-Control-Allow-Origin: {allowed origin} üst bilgisini ayarlar. Örneğin, dağıtılan örnek, Sil düğmesi OPTIONS 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 bilgilerinde, sunucu yanıttaki Access-Control-Allow-Origin üst bilgisini ayarlar.
https://cors1.azurewebsites.net Bu üst bilginin değeri istekten alınan Origin üst bilgiyle eşleşir.
AllowAnyOrigin çağrılırsa, joker karakter değeri olan Access-Control-Allow-Origin: * döndürülür.
AllowAnyOrigin herhangi bir çıkış noktası sağlar.
Yanıt Access-Control-Allow-Origin başlığını içermiyorsa, kaynaklar arası istek başarısız olur. Özellikle, tarayıcı isteğe izin vermemektedir. Sunucu başarılı bir yanıt döndürse bile, tarayıcı yanıtı istemci uygulaması için kullanılabilir hale getirmez.
HTTP'den HTTPS'ye yönlendirme, CORS ön kontrol isteğinde ERR_INVALID_REDIRECT hatasına neden olur
UseHttpsRedirection tarafından HTTPS'ye yönlendirilen, HTTP kullanan bir uç noktaya yapılan istekler ERR_INVALID_REDIRECT on the CORS preflight request ile başarısız olur.
API projeleri, istekleri HTTPS'ye yeniden yönlendirmek için kullanmak UseHttpsRedirection yerine HTTP isteklerini reddedebilir.
SEÇENEKLER isteklerini görüntüleme
Varsayılan olarak, Chrome ve Edge tarayıcıları F12 araçlarının ağ sekmesinde SEÇENEKLER isteklerini göstermez. SEÇENEKLER 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ın.
- restart.
Firefox, SEÇENEKLER isteklerini varsayılan olarak gösterir.
IIS'de CORS
IIS'ye dağıtım yaparken, sunucu anonim erişime izin verecek şekilde yapılandırılmamışsa CORS'nin Windows Kimlik Doğrulamasından önce çalışması gerekir. Bu senaryoyu desteklemek için IIS CORS modülünün uygulama için yüklenmesi ve yapılandırılması gerekir.
CORS'i test edin
Örnek indirmede CORS'yi test etmek için kod bulunur. İndirmeyi öğrenin. Örnek, Razor Pages eklenmiş bir API projesidir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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();
Warning
WithOrigins("https://localhost:<port>");yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıdaki ValuesController, test etmek için uç noktaları sunar:
[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 yukarıdaki örnek kodu test edin:
- Örneği,
dotnet runvarsayılan URL’sini kullanarakhttps://localhost:5001ile çalıştırın. - URL’si
https://localhost:44398olan örneği, bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio’dan çalıştırın.
F12 araçlarıyla tarayıcı kullanma:
Değerler düğmesini seçin ve Ağ sekmesindeki üst bilgileri gözden geçirin.
PUT test düğmesini seçin. OPTIONS isteğinin nasıl görüntüleneceğine ilişkin yönergeler için OPTIONS isteklerini görüntüleme bölümüne bakın. PUT testi iki istek oluşturur: OPTIONS ön uçuş isteği ve PUT isteği.
GetValues2 [DisableCors]Başarısız bir CORS isteğini tetikleme düğmesini seçin. Belgede belirtildiği gibi yanıt 200 başarı 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'origin’inden'https://cors3.azurewebsites.net'konumundaki kaynağa erişim CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
CORS özellikli uç noktalar curl veya Fiddler gibi bir araçla test edilebilir. Bir araç kullanılırken, Origin üst bilgisinde belirtilen isteğin kaynağı, isteği alan ana bilgisayardan farklı olmalıdır. İstek, üst bilgisinin değerine göre Origin değilse:
- CORS ara yazılımının isteği işlemesine gerek yoktur.
- CORS başlıkları yanıtta döndürülmüyor.
Aşağıdaki komut, bilgi içeren bir OPTIONS isteği göndermek için kullanır curl :
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
Uç nokta yönlendirme ve [HttpOptions] ile CORS'i test edin
RequireCors kullanılarak uç nokta bazında CORS'un etkinleştirilmesi şu anda otomatik preflight isteklerini desteklemez. CORS'yi etkinleştirmek için uç nokta yönlendirmesini kullanan aşağıdaki kodu göz önünde bulundurun:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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ğıdaki TodoItems1Controller test amaçlı 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ıma alınmış https://cors1.azurewebsites.net/test?number=1test sayfasından yukarıdaki kodu test edin.
Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur, çünkü uç noktalarında [EnableCors] bulunur ve preflight isteklerine yanıt verirler. Diğer uç noktalar başarısız olur.
JavaScript şunları gönderdiğinden GET düğmesi başarısız oluyor:
headers: {
"Content-Type": "x-custom-header"
},
Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak SEÇENEKLER 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);
}
Yukarıdaki kod, örneği Azure'da dağıtarak test edilebilir. Denetleyici açılır listesinde Preflight'ı ve ardından Denetleyiciyi Ayarla'yı seçin. Uç noktalara yapılan TodoItems2Controller tüm CORS çağrıları başarılı olur.
Ek kaynaklar
Yayımlayanlar Rick Anderson ve Kirk Larkin
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ına hizmet verenden farklı bir etki alanına istekte bulunmasını engeller. Bu kısıtlama aynı çıkış noktası ilkesi olarak adlandırılır. Aynı çıkış noktası ilkesi, kötü amaçlı bir sitenin başka bir siteden hassas verileri okumasını önler. Bazen başka sitelerin uygulamanıza çıkış noktaları arası isteklerde bulunmasına izin vermek isteyebilirsiniz. Daha fazla bilgi için Mozilla CORS makalesine bakın.
Çıkış Noktaları Arası Kaynak Paylaşımı (CORS):
- Bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Bir güvenlik özelliği değildir , CORS güvenliği rahatlatır. CORS'ye izin vererek API daha güvenli değildir. Daha fazla bilgi için bkz . CORS nasıl çalışır?
- Bir sunucunun bazı çıkış noktaları arası isteklere izin verirken diğerlerini reddetmesine izin verir.
- JSONP gibi önceki tekniklerden daha güvenli ve daha esnektir.
Örnek kodu görüntüleme veya indirme (indirme)
Aynı kaynak
Aynı şemalara, konaklara ve bağlantı noktalarına sahip olan iki URL'nin kaynağı aynıdır (RFC 6454).
Bu iki URL'nin kaynağı aynıdır:
https://example.com/foo.htmlhttps://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
-
https://example.net: Farklı alan adı -
https://www.example.com/foo.html: Farklı alt alan adı -
http://example.com/foo.html: Farklı düzen -
https://example.com:9000/foo.html: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- adlı 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ırlama konusunda en iyi denetimi sağlar.
Warning
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz. Ara katman sırası. Örneğin, UseCors kullanılırken UseResponseCachingönce UseResponseCaching çağrılmalıdır.
Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak anlatılır.
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 kaynaklarla uygulamanın tüm 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,
policy =>
{
policy.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ı
_myAllowSpecificOriginsolarak ayarlar. İlke adı rastgeledir. -
UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins.UseCorsCORS ara yazılımını ekler.UseCorsçağrısı,UseRoutingsonrasına ancakUseAuthorizationöncesine yerleştirilmelidir. Daha fazla bilgi için bkz. Ara katman sırası. -
AddCors
çağırır. Lambda bir CorsPolicyBuilder nesne alır.
Yapılandırma seçenekleri, örneğin
WithOrigins, bu makalenin ilerleyen bölümlerinde açıklanmaktadır. -
_myAllowSpecificOriginsTüm denetleyici uç noktaları için CORS ilkesini etkinleştirir. Belirli uç noktalara CORS ilkesi uygulamak için bkz . uç nokta yönlendirmesi . - Yanıt önbelleğe alma ara yazılımını kullanırken, önce UseCorsöğesini çağırınUseResponseCaching.
Uç nokta yönlendirmesinde, CORS ara yazılımı, ile UseRouting çağrıları arasında çalışacak şekilde yapılandırılUseEndpoints.
Önceki koda benzer kodları test etme yönergeleri için Test CORS bölümüne bakın.
Yöntem çağrısı, AddCors CORS hizmetlerini uygulamanın hizmet kapsayıcısına ekler:
public class Startup
{
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
// services.AddResponseCaching();
services.AddControllers();
}
Daha fazla bilgi için bu belgedeki CORS ilkesi seçeneklerine bakın.
Yöntemler CorsPolicyBuilder , aşağıdaki kodda gösterildiği gibi zincirlenebilir:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("http://example.com",
"http://www.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllers();
}
Not: Belirtilen URL sonunda eğik çizgi () içermemelidir./ URL / ile bitiyorsa, karşılaştırma false döndürür ve hiçbir başlık döndürülmez.
Varsayılan ilke ve ara yazılım ile CORS
Aşağıdaki vurgulanmış kod, varsayılan CORS ilkesini etkinleştirir:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.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, varsayılan CORS ilkesini tüm denetleyici uç noktalarına uygular.
Uç nokta yönlendirmesi ile Cors'i etkinleştirme
kullanarak RequireCorsCORS'nin uç nokta başına etkinleştirilmesi otomatik denetim öncesi istekleri desteklemez. Daha fazla bilgi için bu GitHub sorununa bakın ve CORS'yi uç nokta yönlendirme ve [HttpOptions] ile test edin.
Uç nokta yönlendirme ile CORS, uzantı yöntemleri kümesi kullanılarak RequireCors uç nokta temelinde etkinleştirilebilir:
public class Startup
{
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.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();
});
}
}
Önceki kodda:
-
app.UseCorsCORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()başına CORS'yi etkinleştirmez. -
/echove denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir. - Varsayılan bir ilke belirtilmediğinden,
/echo2ve Razor Pages uç noktaları kaynaklar arası isteklere izin vermez.
[DisableCors] özniteliği ile uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmazRequireCors.
Yukarıdakine benzer bir kodu test etme yönergeleri için bkz . Uç nokta yönlendirme ve [HttpOptions] ile CORS'yi test etme.
CorS'yi özniteliklerle etkinleştirme
CORS'yi [EnableCors] özniteliğiyle etkinleştirmek ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulamak en iyi denetimi sağlar.
[EnableCors] özniteliği, CORS'yi genel olarak uygulamaya bir alternatif sağlar.
[EnableCors] özniteliği, tüm uç noktalar yerine seçili uç noktalar için CORS'yi etkinleştirir:
-
[EnableCors]varsayılan ilkeyi belirtir. -
[EnableCors("{Policy String}")]adlandırılmış bir ilke belirtir.
[EnableCors] Özniteliği şu özelliklere uygulanabilir:
-
Razor Sayfa
PageModel - Controller
- Denetleyici eylem yöntemi
[EnableCors] özniteliğiyle denetleyicilere, sayfa modellerine veya eylem yöntemlerine farklı ilkeler uygulanabilir.
[EnableCors] Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve ara yazılımda CORS etkinleştirildiğinde, her iki ilke de uygulanır. İlkeleri birleştirmenizi önermiyoruz. Şunu kullanın
[EnableCors]
öznitelik veya ara yazılım, aynı uygulamada ikisi birden değil.
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 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",
policy =>
{
policy.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("AnotherPolicy",
policy =>
{
policy.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ırlamanın en iyi denetimi için:
-
[EnableCors("MyPolicy")]öğesini adlandırılmış bir ilkeyle kullanın. - Varsayılan bir ilke tanımlamayın.
- Uç nokta yönlendirme kullanmayın.
Sonraki bölümdeki kod önceki listeyi karşılar.
Önceki koda benzer kodları test etme yönergeleri için Test CORS bölümüne bakın.
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 ilkesini "MyPolicy"tanımlar:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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, GetValues2 eylemi için CORS’u devre dışı bırakı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önlendirme ile CORS'yi etkinleştirmez.
- Varsayılan bir CORS ilkesi tanımlamaz.
- Denetleyici için CORS ilkesini etkinleştirmek üzere
"MyPolicy"kullanır. -
GetValues2yöntemi için CORS’u devre dışı bırakır.
Önceki kodu test etmeye ilişkin yönergeler için CORS'u Test Etme bölümüne bakın.
CORS ilke seçenekleri
Bu bölümde, CORS ilkesinde ayarlanabilecek çeşitli seçenekler açıklanmaktadır:
- İzin verilen çıkış noktalarını ayarlama
- İzin verilen HTTP yöntemlerini ayarlama
- İzin verilen istek üst bilgilerini ayarlama
- Açığa çıkarılan yanıt üst bilgilerini ayarlama
- Çapraz kaynak isteklerinde kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde Startup.ConfigureServices çağrılır. Bazı seçenekler için öncelikle CORS'nin çalışma şekli bölümünü okumak yararlı olabilir.
İzin verilen çıkış noktalarını ayarlama
AllowAnyOrigin: Herhangi bir şema (http veya https) ile tüm kaynaklardan GELEN CORS isteklerine izin verir.
AllowAnyOrigin güvenli değildir çünkü herhangi bir web sitesi uygulamaya çıkış noktaları arası isteklerde bulunabilir.
Note
AllowAnyOrigin ve AllowCredentials değerlerinin belirtilmesi güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğine neden olabilir. Bir uygulama her iki yöntemle de 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 üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
SetIsOriginAllowedToAllowWildcardSubdomains: İlkenin IsOriginAllowed özelliğini, kaynağın izin verilip verilmediğini değerlendirirken çıkış noktalarının yapılandırılmış joker karakter etki alanıyla eşleşmesini sağlayan bir işlev olacak şekilde ayarlar.
options.AddPolicy("MyAllowSubdomainPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.SetIsOriginAllowedToAllowWildcardSubdomains();
});
Önceki kodda SetIsOriginAllowedToAllowWildcardSubdomains, joker kökeni "https://*.example.com" ile çağrılır. Bu yapılandırma, example.com gibi https://subdomain.example.com veya https://api.example.com alt etki alanlarından gelen CORS isteklerine izin verir.
* Joker karakterin alt etki alanı eşleştirmeyi etkinleştirmek için kaynağa eklenmesi gerekir.
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Ön kontrol isteklerini ve
Access-Control-Allow-Methodsüst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
İzin verilen istek üst bilgilerini ayarlayın
Bir CORS isteğinde yazar tanımlı istek üst bilgilerinin gönderilmesine izin vermek için WithHeaders çağrısını yapın ve izin verilen üst bilgileri belirtin:
options.AddPolicy("MyAllowHeadersPolicy",
policy =>
{
// requires using Microsoft.Net.Http.Headers;
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Tüm author istek üst bilgilerine izin vermek için AllowAnyHeader çağırın:
options.AddPolicy("MyAllowAllHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
AllowAnyHeader preflight isteklerini ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Ön kontrol istekleri adlı bölüme bakın.
WithHeaders tarafından belirtilen belirli üstbilgilerle eşleşen bir CORS ara yazılım ilkesi, yalnızca Access-Control-Request-Headers içinde gönderilen üstbilgiler WithHeaders içinde belirtilen üstbilgilerle tam olarak eşleştiğinde mümkündür.
Ö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) WithHeaders içinde listelenmediği için aşağıdaki istek üst bilgisine sahip bir ön kontrol isteğini reddeder:
Access-Control-Request-Headers: Cache-Control, Content-Language
Uygulama 200 Tamam yanıtı döndürür ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez.
Erişime açılan yanıt başlıklarını ayarlayın
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 üst bilgileri şunlardır:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına sunmak için WithExposedHeaders çağrısı yapın:
options.AddPolicy("MyExposeResponseHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
Kaynaklar arası isteklerde kimlik bilgileri
Kimlik bilgileri, bir CORS isteğinde özel olarak ele alınmalıdır. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri, tanımlama bilgilerini ve HTTP kimlik doğrulama şemalarını içerir. Farklı kaynaklar arası bir istekle kimlik bilgilerini göndermek için istemci, XMLHttpRequest.withCredentials değerini true olarak ayarlamalıdır.
XMLHttpRequest doğrudan kullanımı:
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;
jQuery kullanma:
$.ajax({
type: 'get',
url: 'https://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
});
fetch('https://www.example.com/api/test', {
credentials: 'include'
});
Sunucunun kimlik bilgilerine izin vermesi gerekir. Kaynaklar arası kimlik bilgilerine izin vermek için AllowCredentials çağırın:
options.AddPolicy("MyMyAllowCredentialsPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.AllowCredentials();
});
HTTP yanıtı, sunucunun kaynaklar arası bir istekte kimlik bilgilerine izin verdiğini tarayıcıya bildiren bir Access-Control-Allow-Credentials üst bilgisi içerir.
Tarayıcı kimlik bilgilerini gönderir ancak yanıt geçerli bir Access-Control-Allow-Credentials başlığı içermiyorsa, tarayıcı yanıtı uygulamanın erişimine açmaz ve kaynaklar arası istek başarısız olur.
Kaynaklar arası kimlik bilgilerine izin vermek güvenlik riskidir. Başka bir etki alanındaki bir web sitesi, kullanıcının bilgisi olmadan oturum açmış bir kullanıcının kimlik bilgilerini kullanıcı adına uygulamaya gönderebilir.
CORS belirtimi ayrıca, "*" üstbilgisi mevcutsa kaynakların Access-Control-Allow-Credentials (tüm kaynaklar) olarak ayarlanmasının geçersiz olduğunu belirtir.
Ön kontrol istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, ön kontrol isteği olarak adlandırılır. Tarayıcı, aşağıdaki koşulların tümü doğruysa ön kontrol isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama,
Accept,Accept-Language,Content-Language,Content-TypeveyaLast-Event-IDdışında istek üst bilgileri ayarlamaz. -
Content-TypeÜst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencodedmultipart/form-datatext/plain
İstemci isteği için ayarlanan istek üst bilgilerine ilişkin kural, uygulamanın setRequestHeader nesnesi üzerinde XMLHttpRequest çağrısı yaparak ayarladığı üst bilgiler için geçerlidir. CORS spesifikasyonu bu üst bilgileri yazar istek üst bilgileri olarak adlandırır. Kural, tarayıcının ayarlayabileceğiniz , User-Agentveya Hostgibi Content-Lengthüst bilgiler için geçerli değildir.
Aşağıda, bu belgenin Test CORS bölümündeki [Test et] düğmesinden yapılan denetim öncesi isteğine benzer bir örnek 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 OPTIONS yöntemini kullanır. Aşağıdaki üst bilgileri içerebilir:
- Access-Control-Request-Method: Gerçek istek için kullanılacak HTTP yöntemi.
-
Access-Control-Request-Headers: Uygulamanın gerçek istekte ayar yaptığı istek üst bilgilerinin listesi. Daha önce belirtildiği gibi, bu, tarayıcının ayardığı üst bilgileri (gibi
User-Agent) içermez. - Access-Control-Allow-Methods
Ön kontrol isteği reddedilirse uygulama 200 OK yanıtı döndürür, ancak CORS başlıklarını ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilmiş bir preflight isteği örneğini görmek için bu belgedeki CORS’yi Test Et bölümüne bakın.
F12 araçlarını kullanarak, konsol uygulaması tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:
- Firefox: Çapraz Kaynak İsteği Engellendi: Aynı Kaynak İlkesi,
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5konumundaki uzak kaynağın okunmasına izin vermiyor. (Neden: CORS isteği başarılı olmadı). Daha fazla bilgi edinin - Chromium tabanlı: 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5' kaynağından 'https://cors3.azurewebsites.net' konumuna getirme erişimi CORS ilkesi tarafından engellendi: Ön kontrol isteğine verilen yanıt, erişim denetimi kontrolünden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
Belirli üstbilgilere izin vermek için WithHeaders çağrısını yapın:
options.AddPolicy("MyAllowHeadersPolicy",
policy =>
{
// requires using Microsoft.Net.Http.Headers;
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Tüm author istek üst bilgilerine izin vermek için AllowAnyHeader çağırın:
options.AddPolicy("MyAllowAllHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
Tarayıcılar, Access-Control-Request-Headers öğesini nasıl ayarladıkları konusunda tutarlı değildir. Aşağıdakilerden biri varsa:
- Üstbilgiler,
"*"dışında herhangi bir değere ayarlanır -
AllowAnyHeader çağrılır: En az
Accept,Content-TypeveOriginile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik ön kontrol isteği kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
-
app.UseCorsiçindeStartup.Configureçağrısı yaparak genel olarak. - özniteliğini
[EnableCors]kullanma.
ASP.NET Core, denetim öncesi SEÇENEKLER isteğine yanıt verir.
RequireCors kullanılarak CORS'nin uç nokta bazında etkinleştirilmesi şu anda otomatik ön kontrol isteklerini desteklemez.
Bu belgenin Test CORS bölümünde bu davranış gösterilmektedir.
Preflight istekleri için [HttpOptions] özniteliği
CORS uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle CORS denetim öncesi isteklerine otomatik olarak yanıt verir. Bazı senaryolarda bu durum söz konusu olmayabilir. Örneğin, uç nokta yönlendirme ile CORS kullanma.
Aşağıdaki kod, OPTIONS 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);
}
Yukarıdaki kodu test etme yönergeleri için Uç nokta yönlendirmesi ve [HttpOptions] ile CORS'yi test etme bölümüne bkz.
Denetim öncesi süre sonu süresini ayarlama
Access-Control-Max-Age üst bilgisi, preflight isteğine verilen yanıtın ne kadar süreyle önbellekte tutulabileceğini belirtir. Bu üst bilgiyi ayarlamak için SetPreflightMaxAge çağrısını yapın:
options.AddPolicy("MySetPreflightExpirationPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
CORS nasıl çalışır?
Bu bölüm, HTTP iletileri düzeyinde bir CORS isteğinde neler olduğunu açıklar.
- CORS bir güvenlik özelliği değildir . CORS, bir sunucunun aynı kaynak ilkesini gevşetmesini sağlayan bir W3C standardıdır.
- Örneğin, kötü niyetli bir aktör sitenize yönelik Siteler Arası Komut Dosyası Çalıştırma (XSS) kullanabilir ve bilgi çalmak için CORS etkinleştirilmiş kendi sitesine siteler arası bir istek gönderebilir.
- CORS'ye izin vererek API daha güvenli değildir.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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
- .NET HttpClient
- Adres çubuğuna URL'yi girerek bir web tarayıcısı.
- CORS'yi zorunlu kılmak istemciye (tarayıcıya) bağlı. 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, bir sunucunun tarayıcıların normalde yasak olacak farklı bir origin’e yönelik XHR veya Fetch API isteği yürütmesine izin vermesinin bir yoludur.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
<script>. Betiklerin farklı kaynaklardan yüklenmesine izin verilir.
- CORS'siz tarayıcılar çıkış noktaları arası istekler yapamaz. CORS'ye başlamadan önce, bu kısıtlamayı aşmak için JSONP kullanıldı. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır
CORS belirtimi, çıkış noktaları arası istekleri etkinleştiren birkaç yeni HTTP üst bilgisi kullanıma sunulmuştur. Tarayıcı CORS'yi destekliyorsa çıkış noktaları arası istekler için bu üst bilgileri otomatik olarak ayarlar. CORS'yi etkinleştirmek için özel JavaScript kodu gerekmez.
Aşağıda, Değerler test düğmesinden https://cors1.azurewebsites.net/api/values konumuna yapılan farklı kaynaktan gelen bir isteğin örneği verilmiştir.
Origin başlığı:
- İstekte bulunan sitenin etki alanını sağlar.
- Zorunludur ve ana bilgisayardan farklı olmalıdır.
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 isteklerinde sunucu, yanıtta Yanıt üst bilgileriAccess-Control-Allow-Origin: {allowed origin} üst bilgisini ayarlar. Örneğin, dağıtılan örnek, Sil düğmesi OPTIONS 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 bilgilerinde, sunucu yanıttaki Access-Control-Allow-Origin üst bilgisini ayarlar.
https://cors1.azurewebsites.net Bu üst bilginin değeri istekten alınan Origin üst bilgiyle eşleşir.
AllowAnyOrigin çağrılırsa, joker karakter değeri olan Access-Control-Allow-Origin: * döndürülür.
AllowAnyOrigin herhangi bir çıkış noktası sağlar.
Yanıt Access-Control-Allow-Origin başlığını içermiyorsa, kaynaklar arası istek başarısız olur. Özellikle, tarayıcı isteğe izin vermemektedir. Sunucu başarılı bir yanıt döndürse bile, tarayıcı yanıtı istemci uygulaması için kullanılabilir hale getirmez.
SEÇENEKLER isteklerini görüntüleme
Varsayılan olarak, Chrome ve Edge tarayıcıları F12 araçlarının ağ sekmesinde SEÇENEKLER isteklerini göstermez. SEÇENEKLER 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ın.
- restart.
Firefox, SEÇENEKLER isteklerini varsayılan olarak gösterir.
IIS'de CORS
IIS'ye dağıtım yaparken, sunucu anonim erişime izin verecek şekilde yapılandırılmamışsa CORS'nin Windows Kimlik Doğrulamasından önce çalışması gerekir. Bu senaryoyu desteklemek için IIS CORS modülünün uygulama için yüklenmesi ve yapılandırılması gerekir.
CORS'i test edin
Örnek indirmede CORS'yi test etmek için kod bulunur. İndirmeyi öğrenin. Örnek, Razor Pages eklenmiş bir API projesidir:
public class StartupTest2
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
policy =>
{
policy.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();
});
}
}
Warning
WithOrigins("https://localhost:<port>");yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıdaki ValuesController, test etmek için uç noktaları sunar:
[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 yukarıdaki örnek kodu test edin:
- Örneği,
dotnet runvarsayılan URL’sini kullanarakhttps://localhost:5001ile çalıştırın. - URL’si
https://localhost:44398olan örneği, bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio’dan çalıştırın.
F12 araçlarıyla tarayıcı kullanma:
Değerler düğmesini seçin ve Ağ sekmesindeki üst bilgileri gözden geçirin.
PUT test düğmesini seçin. OPTIONS isteğinin nasıl görüntüleneceğine ilişkin yönergeler için OPTIONS isteklerini görüntüleme bölümüne bakın. PUT testi iki istek oluşturur: OPTIONS ön uçuş isteği ve PUT isteği.
GetValues2 [DisableCors]Başarısız bir CORS isteğini tetikleme düğmesini seçin. Belgede belirtildiği gibi yanıt 200 başarı 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'origin’inden'https://cors3.azurewebsites.net'konumundaki kaynağa erişim CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi bulunmuyor. Opak yanıt gereksinimlerinize uygunsa, CORS devre dışı bırakılmış olan kaynağı getirmek için isteğin modunu 'cors yok' olarak ayarlayın.
CORS özellikli uç noktalar curl veya Fiddler gibi bir araçla test edilebilir. Bir araç kullanılırken, Origin üst bilgisinde belirtilen isteğin kaynağı, isteği alan ana bilgisayardan farklı olmalıdır. İstek, üst bilgisinin değerine göre Origin değilse:
- CORS ara yazılımının isteği işlemesine gerek yoktur.
- CORS başlıkları yanıtta döndürülmüyor.
Aşağıdaki komut, bilgi içeren bir OPTIONS isteği göndermek için kullanır curl :
curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i
Uç nokta yönlendirme ve [HttpOptions] ile CORS'i test edin
RequireCors kullanılarak uç nokta bazında CORS'un etkinleştirilmesi şu anda otomatik preflight isteklerini desteklemez. CORS'yi etkinleştirmek için uç nokta yönlendirmesini kullanan aşağıdaki kodu göz önünde bulundurun:
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,
policy =>
{
policy.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ğıdaki TodoItems1Controller test amaçlı 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ıma alınmış https://cors1.azurewebsites.net/test?number=1test sayfasından yukarıdaki kodu test edin.
Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur, çünkü uç noktalarında [EnableCors] bulunur ve preflight isteklerine yanıt verirler. Diğer uç noktalar başarısız olur.
JavaScript şunları gönderdiğinden GET düğmesi başarısız oluyor:
headers: {
"Content-Type": "x-custom-header"
},
Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak SEÇENEKLER 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);
}
Yukarıdaki kod, örneği Azure'da dağıtarak test edilebilir. Denetleyici açılır listesinde Preflight'ı ve ardından Denetleyiciyi Ayarla'yı seçin. Uç noktalara yapılan TodoItems2Controller tüm CORS çağrıları başarılı olur.
Ek kaynaklar
ASP.NET Core