ASP.NET Core'da Çıkış Noktaları Arası İstekleri (CORS) Etkinleştirme
Uyarı
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 8 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.html
https://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
https://example.net
: Farklı etki alanıhttps://contoso.example.com/foo.html
: Farklı alt etki alanıhttp://example.com/foo.html
: Farklı düzenhttps://example.com:9000/foo.html
: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- Adlandırılmış ilke veya varsayılan ilke kullanan ara yazılımda.
- Uç nokta yönlendirmeyi kullanma.
- [EnableCors] özniteliğiyle.
[EnableCors] özniteliğini adlandırılmış bir ilkeyle kullanmak, CORS'yi destekleyen uç noktaları sınırlama konusunda en iyi denetimi sağlar.
Uyarı
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz . Ara yazılım siparişi. Ö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ı olarak
_myAllowSpecificOrigins
ayarlar. İlke adı rastgeledir. - UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins
.UseCors
CORS ara yazılımını ekler. çağrısınınUseCors
sonrasında, ancak öncesindeUseAuthorization
yerleştirilmesiUseRouting
gerekir. Daha fazla bilgi için bkz . Ara yazılım siparişi. - Lambda ifadesiyle çağrılarAddCors. Lambda bir CorsPolicyBuilder nesne alır. gibi
WithOrigins
yapılandırma seçenekleri bu makalenin devamında açıklanmıştır. _myAllowSpecificOrigins
Tü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 UseResponseCachingöğesini çağırınUseCors.
Uç nokta yönlendirme ile, CORS ara yazılımının ve çağrıları UseRouting
arasında yürütülecek şekilde yapılandırılması gerekir.UseEndpoints
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 /
sonlandırılırsa, karşılaştırma döndürülür false
ve hiçbir üst bilgi döndürülür.
UseCors ve UseStaticFiles sırası
Genellikle, UseStaticFiles
önce UseCors
çağrılır. Siteler arası statik dosyaları almak için JavaScript kullanan uygulamaların önce UseStaticFiles
çağrısı UseCors
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.UseCors
CORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()
başına CORS'yi etkinleştirmez./echo
ve denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir.- Varsayılan ilke belirtilmediğinden
/echo2
ve Razor Sayfaları uç noktaları çıkış noktaları arası isteklere izin vermez.
[DisableCors] özniteliği ile RequireCors
uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmaz.
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
- Oyun kumandası
- Denetleyici eylem yöntemi
Özniteliğine sahip denetleyicilere, sayfa modellerine veya eylem yöntemlerine [EnableCors]
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 öneririz. CONTACT POINT değerini kopyalamak için ekranın sağ tarafındaki[EnableCors]
özniteliği veya ara yazılım, aynı uygulamada 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:
- Adlandırılmış bir ilkeyle kullanın
[EnableCors("MyPolicy")]
. - Varsayılan ilke tanımlama.
- 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 eylem için CORS'yi GetValues2
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
"MyPolicy"
için [EnableCors("MyPolicy")] kullanır. - yöntemi için CORS'yi
GetValues2
devre dışı bırakır.
Yukarıdaki kodu test etme yönergeleri için bkz . CORS'yi test etme.
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
- Kullanıma sunulan yanıt üst bilgilerini ayarlama
- Çıkış noktaları arası isteklerdeki kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde çağrılır Program.cs
. 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.
Not
ve AllowCredentials
belirtilmesi AllowAnyOrigin
güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğiyle sonuçlanabilir. 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
denetim öncesi istekleri ve Access-Control-Allow-Origin
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne 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();
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Denetim öncesi isteklerini ve
Access-Control-Allow-Methods
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
İzin verilen istek üst bilgilerini ayarlama
Yazar isteği üst bilgileri olarak adlandırılan bir CORS isteğinde belirli üst bilgilerin gönderilmesine izin vermek için, izin verilen üst bilgileri çağırın WithHeaders ve 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 yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
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
denetim öncesi istekleri ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
CORS Ara Yazılım ilkesi, tarafından belirtilen belirli üst bilgilerle WithHeaders
eşleştiğinde Access-Control-Request-Headers
, yalnızca içinde gönderilen üst bilgiler içinde WithHeaders
belirtilen üst bilgilerle 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));
(HeaderNames.ContentLanguage) içinde listelenmediğinden Content-Language
WithHeaders
CORS Ara Yazılımı aşağıdaki istek üst bilgisine sahip bir denetim öncesi 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.
Kullanıma sunulan yanıt üst bilgilerini ayarlama
Varsayılan olarak, tarayıcı tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz . W3C Çıkış Noktaları Arası Kaynak Paylaşımı (Terminoloji): Basit Yanıt Üst Bilgisi.
Varsayılan olarak kullanılabilen yanıt üst bilgileri şunlardır:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına açmak için çağrısı yapın WithExposedHeaders:
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();
Çıkış noktaları arası isteklerdeki kimlik bilgileri
Kimlik bilgileri cors isteğinde özel işleme gerektirir. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri tanımlama bilgilerini ve HTTP kimlik doğrulama düzenlerini içerir. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak true
ayarlanması XMLHttpRequest.withCredentials
gerekir.
Doğrudan kullanarak XMLHttpRequest
:
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. Çıkış noktaları arası kimlik bilgilerine izin vermek için çağrısı:AllowCredentials
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ı, tarayıcıya sunucunun çıkış noktaları arası istek için kimlik bilgilerine izin verdiğinden söz eden bir üst bilgi içerir Access-Control-Allow-Credentials
.
Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli Access-Control-Allow-Credentials
bir üst bilgi içermiyorsa, tarayıcı yanıtı uygulamaya sunmaz ve çıkış noktaları arası istek başarısız olur.
Çıkış noktaları arası kimlik bilgilerine izin vermek bir 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, üst bilgi varsa çıkış noktalarının "*"
(tüm çıkış noktaları) olarak ayarlanmasının Access-Control-Allow-Credentials
geçersiz olduğunu da belirtir.
Denetim öncesi istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, denetim öncesi isteği olarak adlandırılır. Aşağıdaki koşulların tümü doğruysa tarayıcı denetim öncesi isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama , ,
Accept-Language
,Content-Type
Content-Language
veyaLast-Event-ID
dışındaAccept
istek üst bilgileri ayarlamaz. Content-Type
Üst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencoded
multipart/form-data
text/plain
İstemci isteği için ayarlanan istek üst bilgilerinde kural, uygulamanın nesne üzerinde XMLHttpRequest
çağırarak setRequestHeader
ayarladığı üst bilgiler için geçerlidir. CORS belirtimi bu üst bilgileri yazar isteği üst bilgilerini çağırır. Kural, tarayıcının ayarlayabileceğiniz , Host
veya Content-Length
gibi User-Agent
üst bilgiler için geçerli değildir.
Not
Bu makale, örnek kodu iki Azure web sitesine dağıtarak oluşturulan URL'leri içerir ve https://cors.azurewebsites.net
. https://cors3.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
Denetim öncesi 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.
Denetim öncesi isteği reddedilirse uygulama bir 200 OK
yanıt döndürür ancak CORS üst bilgilerini ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilen denetim öncesi isteği örneği için bu belgenin 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: Çıkış Noktaları Arası İstek Engellendi: Aynı Kaynak İlkesi, konumundaki
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5
uzak kaynağın okunmasını engelliyor. (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi - Chromium tabanlı: '' kaynağından 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5https://cors3.azurewebsites.net' konumunda getirme erişimi CORS ilkesi tarafından engellendi: Denetim öncesi isteğine yanıt erişim denetimi denetiminden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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 üst bilgilere izin vermek için çağrısı:WithHeaders
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 yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
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 ayarında Access-Control-Request-Headers
tutarlı değildir. Aşağıdakilerden biri varsa:
- Üst bilgiler,
"*"
- AllowAnyHeader çağrılır: En az
Accept
,Content-Type
veOrigin
ile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik denetim öncesi istek kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
- içinde
Program.cs
arayarakapp.UseCors
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.
Denetim öncesi 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
Üst bilgi, Access-Control-Max-Age
denetim öncesi isteğine verilen yanıtın ne kadar süreyle önbelleğe alınabileceğini belirtir. Bu üst bilgiyi ayarlamak için çağrısı:SetPreflightMaxAge
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ümde, BIR CORS isteğinde HTTP iletileri düzeyinde neler olduğu açıklanmaktadır.
- 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 karşı Siteler Arası Betik (XSS) kullanabilir ve bilgileri çalmak için CORS özellikli sitesine siteler arası bir istek yürütebilir.
- 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 çıkış noktaları arası XHR veya Getirme API'sini yürütmesine izin vermenin bir yoludur ve aksi takdirde yasaktır.
- 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 çıkış noktaları arası 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 öğesine çıkış noktaları arası bir istek örneği verilmiştirhttps://cors1.azurewebsites.net/api/values
. Üst Origin
bilgi:
- İstekte bulunan sitenin etki alanını sağlar.
- Gereklidir ve konaktan 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 ...
İsteklerde OPTIONS
, sunucu yanıttaki Yanıt üst bilgileri Access-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.
çağrılırsa AllowAnyOrigin , Access-Control-Allow-Origin: *
joker karakter değeri döndürülür. AllowAnyOrigin
herhangi bir çıkış noktası sağlar.
Yanıt üst bilgi içermiyorsa Access-Control-Allow-Origin
çıkış noktaları 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.
HTTPS'ye HTTP yeniden yönlendirmesi CORS denetim öncesi isteğinde ERR_INVALID_REDIRECT neden oluyor
ile ERR_INVALID_REDIRECT on the CORS preflight request
başarısız olarak HTTPS'ye yönlendirilen HTTP UseHttpsRedirection kullanan bir uç noktaya yönelik istekler.
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, Sayfaların Razor eklendiği 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();
Uyarı
WithOrigins("https://localhost:<port>");
yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıda ValuesController
test için uç noktalar sağlanı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();
}
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:
- varsayılan URL'sini
https://localhost:5001
kullanarak örneği iledotnet run
çalıştırın. - Url'si
https://localhost:44398
için bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio'dan örneği ç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ğini görüntüleme yönergeleri için bkz . OPTIONS isteklerini görüntüleme. PUT testi iki istek oluşturur: OPTIONS denetim öncesi 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:Kaynaktan
'https://cors3.azurewebsites.net'
getirme'https://cors1.azurewebsites.net/api/values/GetValues2'
erişimi CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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, üst bilgi tarafından belirtilen isteğin Origin
kaynağı, isteği alan konaktan farklı olmalıdır. İstek, üst bilginin değerine Origin
göre çıkış noktaları arası değilse:
- CORS Ara Yazılımının isteği işlemesine gerek yoktur.
- CORS üst bilgileri 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
kullanarak RequireCors
CORS'yi uç nokta temelinde 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.UseEndpoints(endpoints =>
{
endpoints.MapGet("/echo",
context => context.Response.WriteAsync("echo"))
.RequireCors("MyPolicy");
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.Run();
Belirtilen ilkeyi /echo
kullanarak çıkış noktaları arası isteklere izin vermek için yalnızca uç noktanın öğesini kullandığına RequireCors
dikkat edin. Aşağıdaki denetleyiciler [EnableCors] özniteliğini kullanarak CORS'yi etkinleştirir.
Aşağıda TodoItems1Controller
test için uç noktalar sağlanır:
[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);
}
Uç noktaların denetim öncesi istekleri olduğundan [EnableCors]
ve yanıt verdiği için Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur. 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. Denetleyici açılan listesinde Ön Denetim'i 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.html
https://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
https://example.net
: Farklı etki alanıhttps://www.example.com/foo.html
: Farklı alt etki alanıhttp://example.com/foo.html
: Farklı düzenhttps://example.com:9000/foo.html
: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- Adlandırılmış ilke veya varsayılan ilke kullanan ara yazılımda.
- Uç nokta yönlendirmeyi kullanma.
- [EnableCors] özniteliğiyle.
[EnableCors] özniteliğini adlandırılmış bir ilkeyle kullanmak, CORS'yi destekleyen uç noktaları sınırlama konusunda en iyi denetimi sağlar.
Uyarı
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz . Ara yazılım siparişi. Ö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ı olarak
_myAllowSpecificOrigins
ayarlar. İlke adı rastgeledir. - UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins
.UseCors
CORS ara yazılımını ekler. çağrısınınUseCors
sonrasında, ancak öncesindeUseAuthorization
yerleştirilmesiUseRouting
gerekir. Daha fazla bilgi için bkz . Ara yazılım siparişi. - Lambda ifadesiyle çağrılarAddCors. Lambda bir CorsPolicyBuilder nesne alır. gibi
WithOrigins
yapılandırma seçenekleri bu makalenin devamında açıklanmıştır. _myAllowSpecificOrigins
Tü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 UseResponseCachingöğesini çağırınUseCors.
Uç nokta yönlendirme ile, CORS ara yazılımının ve çağrıları UseRouting
arasında yürütülecek şekilde yapılandırılması gerekir.UseEndpoints
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 /
sonlandırılırsa, karşılaştırma döndürülür false
ve hiçbir üst bilgi döndürülür.
Uyarı
UseCors
ve öncesinde UseAuthorization
yerleştirilmelidirUseRouting
. 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
önce UseCors
çağrılır. Siteler arası statik dosyaları almak için JavaScript kullanan uygulamaların önce UseStaticFiles
çağrısı UseCors
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.UseCors
CORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()
başına CORS'yi etkinleştirmez./echo
ve denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir.- Varsayılan ilke belirtilmediğinden
/echo2
ve Razor Sayfaları uç noktaları çıkış noktaları arası isteklere izin vermez.
[DisableCors] özniteliği ile RequireCors
uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmaz.
ASP.NET Core 7.0'da özniteliğin [EnableCors]
bir parametre geçirmesi gerekir veya yoldaki belirsiz bir eşleşmeden ASP0023 Uyarısı oluşturulur. ASP.NET Core 8.0 ve üzeri uyarı oluşturmaz ASP0023
.
[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
- Oyun kumandası
- Denetleyici eylem yöntemi
Özniteliğine sahip denetleyicilere, sayfa modellerine veya eylem yöntemlerine [EnableCors]
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 öneririz. CONTACT POINT değerini kopyalamak için ekranın sağ tarafındaki[EnableCors]
özniteliği veya ara yazılım, aynı uygulamada 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:
- Adlandırılmış bir ilkeyle kullanın
[EnableCors("MyPolicy")]
. - Varsayılan ilke tanımlama.
- 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 eylem için CORS'yi GetValues2
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
"MyPolicy"
için [EnableCors("MyPolicy")] kullanır. - yöntemi için CORS'yi
GetValues2
devre dışı bırakır.
Yukarıdaki kodu test etme yönergeleri için bkz . CORS'yi test etme.
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
- Kullanıma sunulan yanıt üst bilgilerini ayarlama
- Çıkış noktaları arası isteklerdeki kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde çağrılır Program.cs
. 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.
Not
ve AllowCredentials
belirtilmesi AllowAnyOrigin
güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğiyle sonuçlanabilir. 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
denetim öncesi istekleri ve Access-Control-Allow-Origin
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne 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();
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Denetim öncesi isteklerini ve
Access-Control-Allow-Methods
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
İzin verilen istek üst bilgilerini ayarlama
Yazar isteği üst bilgileri olarak adlandırılan bir CORS isteğinde belirli üst bilgilerin gönderilmesine izin vermek için, izin verilen üst bilgileri çağırın WithHeaders ve 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 yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
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
denetim öncesi istekleri ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
CORS Ara Yazılım ilkesi, tarafından belirtilen belirli üst bilgilerle WithHeaders
eşleştiğinde Access-Control-Request-Headers
, yalnızca içinde gönderilen üst bilgiler içinde WithHeaders
belirtilen üst bilgilerle 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));
(HeaderNames.ContentLanguage) içinde listelenmediğinden Content-Language
WithHeaders
CORS Ara Yazılımı aşağıdaki istek üst bilgisine sahip bir denetim öncesi 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.
Kullanıma sunulan yanıt üst bilgilerini ayarlama
Varsayılan olarak, tarayıcı tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz . W3C Çıkış Noktaları Arası Kaynak Paylaşımı (Terminoloji): Basit Yanıt Üst Bilgisi.
Varsayılan olarak kullanılabilen yanıt üst bilgileri şunlardır:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına açmak için çağrısı yapın WithExposedHeaders:
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();
Çıkış noktaları arası isteklerdeki kimlik bilgileri
Kimlik bilgileri cors isteğinde özel işleme gerektirir. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri tanımlama bilgilerini ve HTTP kimlik doğrulama düzenlerini içerir. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak true
ayarlanması XMLHttpRequest.withCredentials
gerekir.
Doğrudan kullanarak XMLHttpRequest
:
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. Çıkış noktaları arası kimlik bilgilerine izin vermek için çağrısı:AllowCredentials
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ı, tarayıcıya sunucunun çıkış noktaları arası istek için kimlik bilgilerine izin verdiğinden söz eden bir üst bilgi içerir Access-Control-Allow-Credentials
.
Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli Access-Control-Allow-Credentials
bir üst bilgi içermiyorsa, tarayıcı yanıtı uygulamaya sunmaz ve çıkış noktaları arası istek başarısız olur.
Çıkış noktaları arası kimlik bilgilerine izin vermek bir 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, üst bilgi varsa çıkış noktalarının "*"
(tüm çıkış noktaları) olarak ayarlanmasının Access-Control-Allow-Credentials
geçersiz olduğunu da belirtir.
Denetim öncesi istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, denetim öncesi isteği olarak adlandırılır. Aşağıdaki koşulların tümü doğruysa tarayıcı denetim öncesi isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama , ,
Accept-Language
,Content-Type
Content-Language
veyaLast-Event-ID
dışındaAccept
istek üst bilgileri ayarlamaz. Content-Type
Üst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencoded
multipart/form-data
text/plain
İstemci isteği için ayarlanan istek üst bilgilerinde kural, uygulamanın nesne üzerinde XMLHttpRequest
çağırarak setRequestHeader
ayarladığı üst bilgiler için geçerlidir. CORS belirtimi bu üst bilgileri yazar isteği üst bilgilerini çağırır. Kural, tarayıcının ayarlayabileceğiniz , Host
veya Content-Length
gibi User-Agent
ü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
Denetim öncesi 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
Denetim öncesi isteği reddedilirse uygulama bir 200 OK
yanıt döndürür ancak CORS üst bilgilerini ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilen denetim öncesi isteği örneği için bu belgenin 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: Çıkış Noktaları Arası İstek Engellendi: Aynı Kaynak İlkesi, konumundaki
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5
uzak kaynağın okunmasını engelliyor. (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi - Chromium tabanlı: '' kaynağından 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5https://cors3.azurewebsites.net' konumunda getirme erişimi CORS ilkesi tarafından engellendi: Denetim öncesi isteğine yanıt erişim denetimi denetiminden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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 üst bilgilere izin vermek için çağrısı:WithHeaders
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 yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
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 ayarında Access-Control-Request-Headers
tutarlı değildir. Aşağıdakilerden biri varsa:
- Üst bilgiler,
"*"
- AllowAnyHeader çağrılır: En az
Accept
,Content-Type
veOrigin
ile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik denetim öncesi istek kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
- içinde
Program.cs
arayarakapp.UseCors
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.
Denetim öncesi 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
Üst bilgi, Access-Control-Max-Age
denetim öncesi isteğine verilen yanıtın ne kadar süreyle önbelleğe alınabileceğini belirtir. Bu üst bilgiyi ayarlamak için çağrısı:SetPreflightMaxAge
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ümde, BIR CORS isteğinde HTTP iletileri düzeyinde neler olduğu açıklanmaktadır.
- 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 karşı Siteler Arası Betik (XSS) kullanabilir ve bilgileri çalmak için CORS özellikli sitesine siteler arası bir istek yürütebilir.
- 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 çıkış noktaları arası XHR veya Getirme API'sini yürütmesine izin vermenin bir yoludur ve aksi takdirde yasaktır.
- 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 çıkış noktaları arası 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.
Üst Origin
bilgi:
- İstekte bulunan sitenin etki alanını sağlar.
- Gereklidir ve konaktan 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 ...
İsteklerde OPTIONS
, sunucu yanıttaki Yanıt üst bilgileri Access-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.
çağrılırsa AllowAnyOrigin , Access-Control-Allow-Origin: *
joker karakter değeri döndürülür. AllowAnyOrigin
herhangi bir çıkış noktası sağlar.
Yanıt üst bilgi içermiyorsa Access-Control-Allow-Origin
çıkış noktaları 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.
HTTPS'ye HTTP yeniden yönlendirmesi CORS denetim öncesi isteğinde ERR_INVALID_REDIRECT neden oluyor
ile ERR_INVALID_REDIRECT on the CORS preflight request
başarısız olarak HTTPS'ye yönlendirilen HTTP UseHttpsRedirection kullanan bir uç noktaya yönelik istekler.
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, Sayfaların Razor eklendiği 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();
Uyarı
WithOrigins("https://localhost:<port>");
yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıda ValuesController
test için uç noktalar sağlanı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();
}
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:
- varsayılan URL'sini
https://localhost:5001
kullanarak örneği iledotnet run
çalıştırın. - Url'si
https://localhost:44398
için bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio'dan örneği ç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ğini görüntüleme yönergeleri için bkz . OPTIONS isteklerini görüntüleme. PUT testi iki istek oluşturur: OPTIONS denetim öncesi 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:Kaynaktan
'https://cors3.azurewebsites.net'
getirme'https://cors1.azurewebsites.net/api/values/GetValues2'
erişimi CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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, üst bilgi tarafından belirtilen isteğin Origin
kaynağı, isteği alan konaktan farklı olmalıdır. İstek, üst bilginin değerine Origin
göre çıkış noktaları arası değilse:
- CORS Ara Yazılımının isteği işlemesine gerek yoktur.
- CORS üst bilgileri 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
kullanarak RequireCors
CORS'yi uç nokta temelinde 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.UseEndpoints(endpoints =>
{
endpoints.MapGet("/echo",
context => context.Response.WriteAsync("echo"))
.RequireCors("MyPolicy");
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.Run();
Belirtilen ilkeyi /echo
kullanarak çıkış noktaları arası isteklere izin vermek için yalnızca uç noktanın öğesini kullandığına RequireCors
dikkat edin. Aşağıdaki denetleyiciler [EnableCors] özniteliğini kullanarak CORS'yi etkinleştirir.
Aşağıda TodoItems1Controller
test için uç noktalar sağlanır:
[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);
}
Uç noktaların denetim öncesi istekleri olduğundan [EnableCors]
ve yanıt verdiği için Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur. 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, denetleyici açılan listesini Azure.In için örneği dağıtarak test edilebilir, Denetim Öncesi'ni 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.html
https://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
https://example.net
: Farklı etki alanıhttps://www.example.com/foo.html
: Farklı alt etki alanıhttp://example.com/foo.html
: Farklı düzenhttps://example.com:9000/foo.html
: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- Adlandırılmış ilke veya varsayılan ilke kullanan ara yazılımda.
- Uç nokta yönlendirmeyi kullanma.
- [EnableCors] özniteliğiyle.
[EnableCors] özniteliğini adlandırılmış bir ilkeyle kullanmak, CORS'yi destekleyen uç noktaları sınırlama konusunda en iyi denetimi sağlar.
Uyarı
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz . Ara yazılım siparişi. Ö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ı olarak
_myAllowSpecificOrigins
ayarlar. İlke adı rastgeledir. - UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins
.UseCors
CORS ara yazılımını ekler. çağrısınınUseCors
sonrasında, ancak öncesindeUseAuthorization
yerleştirilmesiUseRouting
gerekir. Daha fazla bilgi için bkz . Ara yazılım siparişi. - Lambda ifadesiyle çağrılarAddCors. Lambda bir CorsPolicyBuilder nesne alır. gibi
WithOrigins
yapılandırma seçenekleri bu makalenin devamında açıklanmıştır. _myAllowSpecificOrigins
Tü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 UseResponseCachingöğesini çağırınUseCors.
Uç nokta yönlendirme ile, CORS ara yazılımının ve çağrıları UseRouting
arasında yürütülecek şekilde yapılandırılması gerekir.UseEndpoints
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 /
sonlandırılırsa, karşılaştırma döndürülür false
ve hiçbir üst bilgi döndürülür.
Uyarı
UseCors
ve öncesinde UseAuthorization
yerleştirilmelidirUseRouting
. 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
önce UseCors
çağrılır. Siteler arası statik dosyaları almak için JavaScript kullanan uygulamaların önce UseStaticFiles
çağrısı UseCors
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 RequireCors
CORS'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.UseCors
CORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()
başına CORS'yi etkinleştirmez./echo
ve denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir.- Varsayılan ilke belirtilmediğinden
/echo2
ve Razor Sayfaları uç noktaları çıkış noktaları arası isteklere izin vermez.
[DisableCors] özniteliği ile RequireCors
uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmaz.
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
- Oyun kumandası
- Denetleyici eylem yöntemi
Özniteliğine sahip denetleyicilere, sayfa modellerine veya eylem yöntemlerine [EnableCors]
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 öneririz. CONTACT POINT değerini kopyalamak için ekranın sağ tarafındaki[EnableCors]
özniteliği veya ara yazılım, aynı uygulamada 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:
- Adlandırılmış bir ilkeyle kullanın
[EnableCors("MyPolicy")]
. - Varsayılan ilke tanımlama.
- 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 eylem için CORS'yi GetValues2
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
"MyPolicy"
için [EnableCors("MyPolicy")] kullanır. - yöntemi için CORS'yi
GetValues2
devre dışı bırakır.
Yukarıdaki kodu test etme yönergeleri için bkz . CORS'yi test etme.
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
- Kullanıma sunulan yanıt üst bilgilerini ayarlama
- Çıkış noktaları arası isteklerdeki kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde çağrılır Program.cs
. 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.
Not
ve AllowCredentials
belirtilmesi AllowAnyOrigin
güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğiyle sonuçlanabilir. 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
denetim öncesi istekleri ve Access-Control-Allow-Origin
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne 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();
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Denetim öncesi isteklerini ve
Access-Control-Allow-Methods
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
İzin verilen istek üst bilgilerini ayarlama
Yazar isteği üst bilgileri olarak adlandırılan bir CORS isteğinde belirli üst bilgilerin gönderilmesine izin vermek için, izin verilen üst bilgileri çağırın WithHeaders ve 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 yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
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
denetim öncesi istekleri ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
CORS Ara Yazılım ilkesi, tarafından belirtilen belirli üst bilgilerle WithHeaders
eşleştiğinde Access-Control-Request-Headers
, yalnızca içinde gönderilen üst bilgiler içinde WithHeaders
belirtilen üst bilgilerle 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));
(HeaderNames.ContentLanguage) içinde listelenmediğinden Content-Language
WithHeaders
CORS Ara Yazılımı aşağıdaki istek üst bilgisine sahip bir denetim öncesi 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.
Kullanıma sunulan yanıt üst bilgilerini ayarlama
Varsayılan olarak, tarayıcı tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz . W3C Çıkış Noktaları Arası Kaynak Paylaşımı (Terminoloji): Basit Yanıt Üst Bilgisi.
Varsayılan olarak kullanılabilen yanıt üst bilgileri şunlardır:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına açmak için çağrısı yapın WithExposedHeaders:
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();
Çıkış noktaları arası isteklerdeki kimlik bilgileri
Kimlik bilgileri cors isteğinde özel işleme gerektirir. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri tanımlama bilgilerini ve HTTP kimlik doğrulama düzenlerini içerir. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak true
ayarlanması XMLHttpRequest.withCredentials
gerekir.
Doğrudan kullanarak XMLHttpRequest
:
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. Çıkış noktaları arası kimlik bilgilerine izin vermek için çağrısı:AllowCredentials
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ı, tarayıcıya sunucunun çıkış noktaları arası istek için kimlik bilgilerine izin verdiğinden söz eden bir üst bilgi içerir Access-Control-Allow-Credentials
.
Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli Access-Control-Allow-Credentials
bir üst bilgi içermiyorsa, tarayıcı yanıtı uygulamaya sunmaz ve çıkış noktaları arası istek başarısız olur.
Çıkış noktaları arası kimlik bilgilerine izin vermek bir 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, üst bilgi varsa çıkış noktalarının "*"
(tüm çıkış noktaları) olarak ayarlanmasının Access-Control-Allow-Credentials
geçersiz olduğunu da belirtir.
Denetim öncesi istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, denetim öncesi isteği olarak adlandırılır. Aşağıdaki koşulların tümü doğruysa tarayıcı denetim öncesi isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama , ,
Accept-Language
,Content-Type
Content-Language
veyaLast-Event-ID
dışındaAccept
istek üst bilgileri ayarlamaz. Content-Type
Üst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencoded
multipart/form-data
text/plain
İstemci isteği için ayarlanan istek üst bilgilerinde kural, uygulamanın nesne üzerinde XMLHttpRequest
çağırarak setRequestHeader
ayarladığı üst bilgiler için geçerlidir. CORS belirtimi bu üst bilgileri yazar isteği üst bilgilerini çağırır. Kural, tarayıcının ayarlayabileceğiniz , Host
veya Content-Length
gibi User-Agent
ü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
Denetim öncesi 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
Denetim öncesi isteği reddedilirse uygulama bir 200 OK
yanıt döndürür ancak CORS üst bilgilerini ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilen denetim öncesi isteği örneği için bu belgenin 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: Çıkış Noktaları Arası İstek Engellendi: Aynı Kaynak İlkesi, konumundaki
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5
uzak kaynağın okunmasını engelliyor. (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi - Chromium tabanlı: '' kaynağından 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5https://cors3.azurewebsites.net' konumunda getirme erişimi CORS ilkesi tarafından engellendi: Denetim öncesi isteğine yanıt erişim denetimi denetiminden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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 üst bilgilere izin vermek için çağrısı:WithHeaders
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 yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
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 ayarında Access-Control-Request-Headers
tutarlı değildir. Aşağıdakilerden biri varsa:
- Üst bilgiler,
"*"
- AllowAnyHeader çağrılır: En az
Accept
,Content-Type
veOrigin
ile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik denetim öncesi istek kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
- içinde
Program.cs
arayarakapp.UseCors
genel olarak. - özniteliğini
[EnableCors]
kullanma.
ASP.NET Core, denetim öncesi SEÇENEKLER isteğine yanıt verir.
CorS'nin şu anda kullanarak uç nokta başına etkinleştirilmesi RequireCors
otomatik denetim öncesi istekleri desteklemez.
Bu belgenin Test CORS bölümünde bu davranış gösterilmektedir.
Denetim öncesi 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 bkz . Uç nokta yönlendirmesi ile CORS'yi test etme ve [HttpOptions] .
Denetim öncesi süre sonu süresini ayarlama
Üst bilgi, Access-Control-Max-Age
denetim öncesi isteğine verilen yanıtın ne kadar süreyle önbelleğe alınabileceğini belirtir. Bu üst bilgiyi ayarlamak için çağrısı:SetPreflightMaxAge
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ümde, BIR CORS isteğinde HTTP iletileri düzeyinde neler olduğu açıklanmaktadır.
- 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 karşı Siteler Arası Betik (XSS) kullanabilir ve bilgileri çalmak için CORS özellikli sitesine siteler arası bir istek yürütebilir.
- 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 çıkış noktaları arası XHR veya Getirme API'sini yürütmesine izin vermenin bir yoludur ve aksi takdirde yasaktır.
- 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 çıkış noktaları arası 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 öğesine çıkış noktaları arası bir istek örneği verilmiştirhttps://cors1.azurewebsites.net/api/values
. Üst Origin
bilgi:
- İstekte bulunan sitenin etki alanını sağlar.
- Gereklidir ve konaktan 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 ...
İsteklerde OPTIONS
, sunucu yanıttaki Yanıt üst bilgileri Access-Control-Allow-Origin: {allowed origin}
üst bilgisini ayarlar. Örneğin, dağıtılan 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.
çağrılırsa AllowAnyOrigin , Access-Control-Allow-Origin: *
joker karakter değeri döndürülür. AllowAnyOrigin
herhangi bir çıkış noktası sağlar.
Yanıt üst bilgi içermiyorsa Access-Control-Allow-Origin
çıkış noktaları 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.
HTTPS'ye HTTP yeniden yönlendirmesi CORS denetim öncesi isteğinde ERR_INVALID_REDIRECT neden oluyor
ile ERR_INVALID_REDIRECT on the CORS preflight request
başarısız olarak HTTPS'ye yönlendirilen HTTP UseHttpsRedirection kullanan bir uç noktaya yönelik istekler.
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-cors
veyaedge://flags/#out-of-blink-cors
- bayrağını devre dışı bırakın.
- Yeni -den başlatın.
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, Sayfaların Razor eklendiği 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();
Uyarı
WithOrigins("https://localhost:<port>");
yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıda ValuesController
test için uç noktalar sağlanı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();
}
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:
- varsayılan URL'sini
https://localhost:5001
kullanarak örneği iledotnet run
çalıştırın. - Url'si
https://localhost:44398
için bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio'dan örneği ç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ğini görüntüleme yönergeleri için bkz . OPTIONS isteklerini görüntüleme. PUT testi iki istek oluşturur: OPTIONS denetim öncesi 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:Kaynaktan
'https://cors3.azurewebsites.net'
getirme'https://cors1.azurewebsites.net/api/values/GetValues2'
erişimi CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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, üst bilgi tarafından belirtilen isteğin Origin
kaynağı, isteği alan konaktan farklı olmalıdır. İstek, üst bilginin değerine Origin
göre çıkış noktaları arası değilse:
- CORS Ara Yazılımının isteği işlemesine gerek yoktur.
- CORS üst bilgileri 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
CorS'nin şu anda kullanarak uç nokta başına etkinleştirilmesi RequireCors
otomatik denetim öncesi istekleri 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ğıda TodoItems1Controller
test için uç noktalar sağlanır:
[Route("api/[controller]")]
[ApiController]
public class TodoItems1Controller : ControllerBase
{
// PUT: api/TodoItems1/5
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return Content($"ID = {id}");
}
return ControllerContext.MyDisplayRouteInfo(id);
}
// Delete: api/TodoItems1/5
[HttpDelete("{id}")]
public IActionResult MyDelete(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/TodoItems1
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors]
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
// Delete: api/TodoItems1/MyDelete2/5
[EnableCors]
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Dağıtılan örneğin test sayfasından (https://cors1.azurewebsites.net/test?number=1
) önceki kodu test edin.
Uç noktaların denetim öncesi istekleri olduğundan [EnableCors]
ve yanıt verdiği için Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur. 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, denetleyici açılan listesini Azure.In için örneği dağıtarak test edilebilir, Denetim Öncesi'ni 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.html
https://example.com/bar.html
Bu URL'lerin çıkış noktaları önceki iki URL'den farklı:
https://example.net
: Farklı etki alanıhttps://www.example.com/foo.html
: Farklı alt etki alanıhttp://example.com/foo.html
: Farklı düzenhttps://example.com:9000/foo.html
: Farklı bağlantı noktası
CORS'yi etkinleştirme
CORS'yi etkinleştirmenin üç yolu vardır:
- Adlandırılmış ilke veya varsayılan ilke kullanan ara yazılımda.
- Uç nokta yönlendirmeyi kullanma.
- [EnableCors] özniteliğiyle.
[EnableCors] özniteliğini adlandırılmış bir ilkeyle kullanmak, CORS'yi destekleyen uç noktaları sınırlama konusunda en iyi denetimi sağlar.
Uyarı
UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz . Ara yazılım siparişi. Ö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ı olarak
_myAllowSpecificOrigins
ayarlar. İlke adı rastgeledir. - UseCors Uzantı yöntemini çağırır ve CORS ilkesini belirtir
_myAllowSpecificOrigins
.UseCors
CORS ara yazılımını ekler. çağrısınınUseCors
sonrasında, ancak öncesindeUseAuthorization
yerleştirilmesiUseRouting
gerekir. Daha fazla bilgi için bkz . Ara yazılım siparişi. - Lambda ifadesiyle çağrılarAddCors. Lambda bir CorsPolicyBuilder nesne alır. gibi
WithOrigins
yapılandırma seçenekleri bu makalenin devamında açıklanmıştır. _myAllowSpecificOrigins
Tü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 UseResponseCachingöğesini çağırınUseCors.
Uç nokta yönlendirme ile, CORS ara yazılımının ve çağrıları UseRouting
arasında yürütülecek şekilde yapılandırılması gerekir.UseEndpoints
Yukarıdaki koda benzer şekilde kodu test etme yönergeleri için bkz . CORS'yi test etme.
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 /
sonlandırılırsa, karşılaştırma döndürülür false
ve hiçbir üst bilgi döndürülür.
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 RequireCors
CORS'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.UseCors
CORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tekapp.UseCors()
başına CORS'yi etkinleştirmez./echo
ve denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir.- Varsayılan ilke belirtilmediğinden
/echo2
ve Razor Sayfaları uç noktaları çıkış noktaları arası isteklere izin vermez.
[DisableCors] özniteliği ile RequireCors
uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmaz.
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
- Oyun kumandası
- Denetleyici eylem yöntemi
Özniteliğine sahip denetleyicilere, sayfa modellerine veya eylem yöntemlerine [EnableCors]
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 öneririz. CONTACT POINT değerini kopyalamak için ekranın sağ tarafındaki[EnableCors]
özniteliği veya ara yazılım, aynı uygulamada 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:
- Adlandırılmış bir ilkeyle kullanın
[EnableCors("MyPolicy")]
. - Varsayılan ilke tanımlama.
- Uç nokta yönlendirme kullanmayın.
Sonraki bölümdeki kod önceki listeyi karşılar.
Yukarıdaki koda benzer şekilde kodu test etme yönergeleri için bkz . CORS'yi test etme.
CORS'yi devre dışı bırakma
[DisableCors] özniteliği, uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmaz.
Aşağıdaki kod CORS 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 eylem için CORS'yi GetValues2
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
"MyPolicy"
için [EnableCors("MyPolicy")] kullanır. - yöntemi için CORS'yi
GetValues2
devre dışı bırakır.
Yukarıdaki kodu test etme yönergeleri için bkz . CORS'yi test etme.
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
- Kullanıma sunulan yanıt üst bilgilerini ayarlama
- Çıkış noktaları arası isteklerdeki kimlik bilgileri
- Denetim öncesi süre sonu süresini ayarlama
AddPolicy içinde çağrılır Startup.ConfigureServices
. 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.
Not
ve AllowCredentials
belirtilmesi AllowAnyOrigin
güvenli olmayan bir yapılandırmadır ve siteler arası istek sahteciliğiyle sonuçlanabilir. 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
denetim öncesi istekleri ve Access-Control-Allow-Origin
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne 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();
});
İzin verilen HTTP yöntemlerini ayarlama
- Herhangi bir HTTP yöntemine izin verir:
- Denetim öncesi isteklerini ve
Access-Control-Allow-Methods
üst bilgiyi etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
İzin verilen istek üst bilgilerini ayarlama
Yazar isteği üst bilgileri olarak adlandırılan bir CORS isteğinde belirli üst bilgilerin gönderilmesine izin vermek için, izin verilen üst bilgileri çağırın WithHeaders ve belirtin:
options.AddPolicy("MyAllowHeadersPolicy",
policy =>
{
// requires using Microsoft.Net.Http.Headers;
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Tüm yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
options.AddPolicy("MyAllowAllHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
AllowAnyHeader
denetim öncesi istekleri ve Access-Control-Request-Headers üst bilgisini etkiler. Daha fazla bilgi için Denetim öncesi istekleri bölümüne bakın.
CORS Ara Yazılım ilkesi, tarafından belirtilen belirli üst bilgilerle WithHeaders
eşleştiğinde Access-Control-Request-Headers
, yalnızca içinde gönderilen üst bilgiler içinde WithHeaders
belirtilen üst bilgilerle 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));
(HeaderNames.ContentLanguage) içinde listelenmediğinden Content-Language
WithHeaders
CORS Ara Yazılımı aşağıdaki istek üst bilgisine sahip bir denetim öncesi 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.
Kullanıma sunulan yanıt üst bilgilerini ayarlama
Varsayılan olarak, tarayıcı tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz . W3C Çıkış Noktaları Arası Kaynak Paylaşımı (Terminoloji): Basit Yanıt Üst Bilgisi.
Varsayılan olarak kullanılabilen yanıt üst bilgileri şunlardır:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
CORS belirtimi bu üst bilgileri basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulamanın kullanımına açmak için çağrısı yapın WithExposedHeaders:
options.AddPolicy("MyExposeResponseHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
Çıkış noktaları arası isteklerdeki kimlik bilgileri
Kimlik bilgileri cors isteğinde özel işleme gerektirir. Varsayılan olarak, tarayıcı çıkış noktaları arası bir istekle kimlik bilgileri göndermez. Kimlik bilgileri tanımlama bilgilerini ve HTTP kimlik doğrulama düzenlerini içerir. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak true
ayarlanması XMLHttpRequest.withCredentials
gerekir.
Doğrudan kullanarak XMLHttpRequest
:
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. Çıkış noktaları arası kimlik bilgilerine izin vermek için çağrısı:AllowCredentials
options.AddPolicy("MyMyAllowCredentialsPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.AllowCredentials();
});
HTTP yanıtı, tarayıcıya sunucunun çıkış noktaları arası istek için kimlik bilgilerine izin verdiğinden söz eden bir üst bilgi içerir Access-Control-Allow-Credentials
.
Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli Access-Control-Allow-Credentials
bir üst bilgi içermiyorsa, tarayıcı yanıtı uygulamaya sunmaz ve çıkış noktaları arası istek başarısız olur.
Çıkış noktaları arası kimlik bilgilerine izin vermek bir 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, üst bilgi varsa çıkış noktalarının "*"
(tüm çıkış noktaları) olarak ayarlanmasının Access-Control-Allow-Credentials
geçersiz olduğunu da belirtir.
Denetim öncesi istekleri
Bazı CORS istekleri için tarayıcı, gerçek isteği yapmadan önce ek bir OPTIONS isteği gönderir. Bu istek, denetim öncesi isteği olarak adlandırılır. Aşağıdaki koşulların tümü doğruysa tarayıcı denetim öncesi isteğini atlayabilir:
- İstek yöntemi GET, HEAD veya POST şeklindedir.
- Uygulama , ,
Accept-Language
,Content-Type
Content-Language
veyaLast-Event-ID
dışındaAccept
istek üst bilgileri ayarlamaz. Content-Type
Üst bilgi ayarlanırsa aşağıdaki değerlerden birine sahiptir:application/x-www-form-urlencoded
multipart/form-data
text/plain
İstemci isteği için ayarlanan istek üst bilgilerinde kural, uygulamanın nesne üzerinde XMLHttpRequest
çağırarak setRequestHeader
ayarladığı üst bilgiler için geçerlidir. CORS belirtimi bu üst bilgileri yazar isteği üst bilgilerini çağırır. Kural, tarayıcının ayarlayabileceğiniz , Host
veya Content-Length
gibi User-Agent
ü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
Denetim öncesi 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
Denetim öncesi isteği reddedilirse uygulama bir 200 OK
yanıt döndürür ancak CORS üst bilgilerini ayarlamaz. Bu nedenle tarayıcı çıkış noktaları arası isteği denemez. Reddedilen denetim öncesi isteği örneği için bu belgenin 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: Çıkış Noktaları Arası İstek Engellendi: Aynı Kaynak İlkesi, konumundaki
https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5
uzak kaynağın okunmasını engelliyor. (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi - Chromium tabanlı: '' kaynağından 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5https://cors3.azurewebsites.net' konumunda getirme erişimi CORS ilkesi tarafından engellendi: Denetim öncesi isteğine yanıt erişim denetimi denetiminden geçmiyor: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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 üst bilgilere izin vermek için çağrısı:WithHeaders
options.AddPolicy("MyAllowHeadersPolicy",
policy =>
{
// requires using Microsoft.Net.Http.Headers;
policy.WithOrigins("http://example.com")
.WithHeaders(HeaderNames.ContentType, "x-custom-header");
});
Tüm yazar isteği üst bilgilerine izin vermek için çağrısı:AllowAnyHeader
options.AddPolicy("MyAllowAllHeadersPolicy",
policy =>
{
policy.WithOrigins("https://*.example.com")
.AllowAnyHeader();
});
Tarayıcılar ayarında Access-Control-Request-Headers
tutarlı değildir. Aşağıdakilerden biri varsa:
- Üst bilgiler,
"*"
- AllowAnyHeader çağrılır: En az
Accept
,Content-Type
veOrigin
ile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.
Otomatik denetim öncesi istek kodu
CORS ilkesi aşağıdakilerden biri uygulandığında:
- içinde
Startup.Configure
arayarakapp.UseCors
genel olarak. - özniteliğini
[EnableCors]
kullanma.
ASP.NET Core, denetim öncesi SEÇENEKLER isteğine yanıt verir.
CorS'nin şu anda kullanarak uç nokta başına etkinleştirilmesi RequireCors
otomatik denetim öncesi istekleri desteklemez.
Bu belgenin Test CORS bölümünde bu davranış gösterilmektedir.
Denetim öncesi 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 bkz . Uç nokta yönlendirmesi ile CORS'yi test etme ve [HttpOptions] .
Denetim öncesi süre sonu süresini ayarlama
Üst bilgi, Access-Control-Max-Age
denetim öncesi isteğine verilen yanıtın ne kadar süreyle önbelleğe alınabileceğini belirtir. Bu üst bilgiyi ayarlamak için çağrısı:SetPreflightMaxAge
options.AddPolicy("MySetPreflightExpirationPolicy",
policy =>
{
policy.WithOrigins("http://example.com")
.SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
});
CORS nasıl çalışır?
Bu bölümde, BIR CORS isteğinde HTTP iletileri düzeyinde neler olduğu açıklanmaktadır.
- 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 karşı Siteler Arası Betik (XSS) kullanabilir ve bilgileri çalmak için CORS özellikli sitesine siteler arası bir istek yürütebilir.
- 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 çıkış noktaları arası XHR veya Getirme API'sini yürütmesine izin vermenin bir yoludur ve aksi takdirde yasaktır.
- 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 çıkış noktaları arası 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 öğesine çıkış noktaları arası bir istek örneği verilmiştirhttps://cors1.azurewebsites.net/api/values
. Üst Origin
bilgi:
- İstekte bulunan sitenin etki alanını sağlar.
- Gereklidir ve konaktan 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 ...
İsteklerde OPTIONS
, sunucu yanıttaki Yanıt üst bilgileri Access-Control-Allow-Origin: {allowed origin}
üst bilgisini ayarlar. Örneğin, dağıtılan 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.
çağrılırsa AllowAnyOrigin , Access-Control-Allow-Origin: *
joker karakter değeri döndürülür. AllowAnyOrigin
herhangi bir çıkış noktası sağlar.
Yanıt üst bilgi içermiyorsa Access-Control-Allow-Origin
çıkış noktaları 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-cors
veyaedge://flags/#out-of-blink-cors
- bayrağını devre dışı bırakın.
- Yeni -den başlatın.
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, Sayfaların Razor eklendiği 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();
});
}
}
Uyarı
WithOrigins("https://localhost:<port>");
yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.
Aşağıda ValuesController
test için uç noktalar sağlanı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();
}
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:
- varsayılan URL'sini
https://localhost:5001
kullanarak örneği iledotnet run
çalıştırın. - Url'si
https://localhost:44398
için bağlantı noktası 44398 olarak ayarlanmış şekilde Visual Studio'dan örneği ç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ğini görüntüleme yönergeleri için bkz . OPTIONS isteklerini görüntüleme. PUT testi iki istek oluşturur: OPTIONS denetim öncesi 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:Kaynaktan
'https://cors3.azurewebsites.net'
getirme'https://cors1.azurewebsites.net/api/values/GetValues2'
erişimi CORS ilkesi tarafından engellendi: İstenen kaynakta 'Access-Control-Allow-Origin' üst bilgisi yok. 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, üst bilgi tarafından belirtilen isteğin Origin
kaynağı, isteği alan konaktan farklı olmalıdır. İstek, üst bilginin değerine Origin
göre çıkış noktaları arası değilse:
- CORS Ara Yazılımının isteği işlemesine gerek yoktur.
- CORS üst bilgileri 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
CorS'nin şu anda kullanarak uç nokta başına etkinleştirilmesi RequireCors
otomatik denetim öncesi istekleri 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ğıda TodoItems1Controller
test için uç noktalar sağlanır:
[Route("api/[controller]")]
[ApiController]
public class TodoItems1Controller : ControllerBase
{
// PUT: api/TodoItems1/5
[HttpPut("{id}")]
public IActionResult PutTodoItem(int id)
{
if (id < 1)
{
return Content($"ID = {id}");
}
return ControllerContext.MyDisplayRouteInfo(id);
}
// Delete: api/TodoItems1/5
[HttpDelete("{id}")]
public IActionResult MyDelete(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
// GET: api/TodoItems1
[HttpGet]
public IActionResult GetTodoItems() =>
ControllerContext.MyDisplayRouteInfo();
[EnableCors]
[HttpGet("{action}")]
public IActionResult GetTodoItems2() =>
ControllerContext.MyDisplayRouteInfo();
// Delete: api/TodoItems1/MyDelete2/5
[EnableCors]
[HttpDelete("{action}/{id}")]
public IActionResult MyDelete2(int id) =>
ControllerContext.MyDisplayRouteInfo(id);
}
Dağıtılan örneğin test sayfasından (https://cors1.azurewebsites.net/test?number=1
) önceki kodu test edin.
Uç noktaların denetim öncesi istekleri olduğundan [EnableCors]
ve yanıt verdiği için Delete [EnableCors] ve GET [EnableCors] düğmeleri başarılı olur. 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, denetleyici açılan listesini Azure.In için örneği dağıtarak test edilebilir, Denetim Öncesi'ni 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