ASP.NET Core'da Çıkış Noktaları Arası İstekleri (CORS) Etkinleştirme

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin ASP.NET Core 8.0 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.
  • ONP gibi JSö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üzen
  • https://example.com:9000/foo.html: Farklı bağlantı noktası

CORS'yi etkinleştirme

CORS'yi etkinleştirmenin üç yolu vardır:

[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:

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:

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 tek app.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 RequireCorsuç 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 Sayfası 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.

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:

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:

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:

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

AllowAnyMethod:

  • 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 WithHeadersbelirtilen ü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-LanguageWithHeadersCORS 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 s ve HTTP kimlik doğrulama düzenlerini içerir cookie. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak trueayarlanması 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 API'sini kullanma:

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-TypeContent-Languageveya Last-Event-IDdışında Acceptistek ü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 , Hostveya Content-Lengthgibi 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:

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/5uzak 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-Headerstutarlı değildir. Aşağıdakilerden biri varsa:

  • Üst bilgiler, "*"
  • AllowAnyHeader çağrılır: En az Accept, Content-Typeve Originile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.

Otomatik denetim öncesi istek kodu

CORS ilkesi aşağıdakilerden biri uygulandığında:

  • içinde Program.csarayarak app.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:
  • 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'nin öncesinde, JSbu kısıtlamayı aşmak için ONP kullanılıyordu. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır <script> . Betiklerin çıkış noktaları arası yüklenmesine izin verilir.

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 örnekteki PUT test düğmesi

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 bilgileriAccess-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 requestbaş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:

  • adresinde https://cors3.azurewebsites.net/dağıtılan örnek uygulamayı kullanın. Örneği indirmeniz gerekmez.
  • varsayılan URL'sini https://localhost:5001kullanarak örneği ile dotnet run çalıştırın.
  • Url'si https://localhost:44398iç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 RequireCorsCORS'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);
}

Dağıtılan örneğin test sayfasından ö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] //  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);
}

Dağıtılan örneğin test sayfasından önceki kodu test edin. 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.
  • ONP gibi JSö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üzen
  • https://example.com:9000/foo.html: Farklı bağlantı noktası

CORS'yi etkinleştirme

CORS'yi etkinleştirmenin üç yolu vardır:

[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:

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:

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ı

UseCorsve öncesinde UseAuthorizationyerleş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 tek app.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 RequireCorsuç 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 Sayfası 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.

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:

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:

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:

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

AllowAnyMethod:

  • 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 WithHeadersbelirtilen ü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-LanguageWithHeadersCORS 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 s ve HTTP kimlik doğrulama düzenlerini içerir cookie. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak trueayarlanması 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 API'sini kullanma:

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-TypeContent-Languageveya Last-Event-IDdışında Acceptistek ü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 , Hostveya Content-Lengthgibi 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:

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/5uzak 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-Headerstutarlı değildir. Aşağıdakilerden biri varsa:

  • Üst bilgiler, "*"
  • AllowAnyHeader çağrılır: En az Accept, Content-Typeve Originile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.

Otomatik denetim öncesi istek kodu

CORS ilkesi aşağıdakilerden biri uygulandığında:

  • içinde Program.csarayarak app.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:
  • 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'nin öncesinde, JSbu kısıtlamayı aşmak için ONP kullanılıyordu. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır <script> . Betiklerin çıkış noktaları arası yüklenmesine izin verilir.

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 örnekteki PUT test düğmesi

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 bilgileriAccess-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 requestbaş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:

  • adresinde https://cors3.azurewebsites.net/dağıtılan örnek uygulamayı kullanın. Örneği indirmeniz gerekmez.
  • varsayılan URL'sini https://localhost:5001kullanarak örneği ile dotnet run çalıştırın.
  • Url'si https://localhost:44398iç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 RequireCorsCORS'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);
}

Dağıtılan örneğin test sayfasından ö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] //  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);
}

Dağıtılan örneğin test sayfasından önceki kodu test edin. 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.
  • ONP gibi JSö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üzen
  • https://example.com:9000/foo.html: Farklı bağlantı noktası

CORS'yi etkinleştirme

CORS'yi etkinleştirmenin üç yolu vardır:

[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:

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:

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ı

UseCorsve öncesinde UseAuthorizationyerleş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 RequireCorsCORS'nin uç nokta başına etkinleştirilmesi otomatik denetim öncesi istekleri desteklemez. Daha fazla bilgi için bu GitHub sorununa bakın ve CORS'yi uç nokta yönlendirme ve [HttpOptions] ile test edin.

Uç nokta yönlendirme ile CORS, uzantı yöntemleri kümesi kullanılarak RequireCors uç nokta temelinde etkinleştirilebilir:

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      policy =>
                      {
                          policy.WithOrigins("http://example.com",
                                              "http://www.contoso.com");
                      });
});

builder.Services.AddControllers();
builder.Services.AddRazorPages();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/echo",
        context => context.Response.WriteAsync("echo"))
        .RequireCors(MyAllowSpecificOrigins);

    endpoints.MapControllers()
             .RequireCors(MyAllowSpecificOrigins);

    endpoints.MapGet("/echo2",
        context => context.Response.WriteAsync("echo2"));

    endpoints.MapRazorPages();
});

app.Run();

Önceki kodda:

  • app.UseCors CORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tek app.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 RequireCorsuç 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 Sayfası 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.

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:

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:

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:

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

AllowAnyMethod:

  • 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 WithHeadersbelirtilen ü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-LanguageWithHeadersCORS 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 s ve HTTP kimlik doğrulama düzenlerini içerir cookie. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak trueayarlanması 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 API'sini kullanma:

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-TypeContent-Languageveya Last-Event-IDdışında Acceptistek ü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 , Hostveya Content-Lengthgibi 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:

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/5uzak 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-Headerstutarlı değildir. Aşağıdakilerden biri varsa:

  • Üst bilgiler, "*"
  • AllowAnyHeader çağrılır: En az Accept, Content-Typeve Originile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.

Otomatik denetim öncesi istek kodu

CORS ilkesi aşağıdakilerden biri uygulandığında:

  • içinde Program.csarayarak app.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:
  • 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'nin öncesinde, JSbu kısıtlamayı aşmak için ONP kullanılıyordu. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır <script> . Betiklerin çıkış noktaları arası yüklenmesine izin verilir.

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 örnekteki PUT test düğmesi

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 bilgileriAccess-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 requestbaş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 veya edge://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:

  • adresinde https://cors3.azurewebsites.net/dağıtılan örnek uygulamayı kullanın. Örneği indirmeniz gerekmez.
  • varsayılan URL'sini https://localhost:5001kullanarak örneği ile dotnet run çalıştırın.
  • Url'si https://localhost:44398iç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 ö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);
}

Dağıtılan örneğin test sayfasından önceki kodu test edin. 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.
  • ONP gibi JSö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üzen
  • https://example.com:9000/foo.html: Farklı bağlantı noktası

CORS'yi etkinleştirme

CORS'yi etkinleştirmenin üç yolu vardır:

[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:

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 RequireCorsCORS'nin uç nokta başına etkinleştirilmesi otomatik denetim öncesi istekleri desteklemez. Daha fazla bilgi için bu GitHub sorununa bakın ve CORS'yi uç nokta yönlendirme ve [HttpOptions] ile test edin.

Uç nokta yönlendirme ile CORS, uzantı yöntemleri kümesi kullanılarak RequireCors uç nokta temelinde etkinleştirilebilir:

public class Startup
{
    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: MyAllowSpecificOrigins,
                              policy =>
                              {
                                  policy.WithOrigins("http://example.com",
                                                      "http://www.contoso.com");
                              });
        });

        services.AddControllers();
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/echo",
                context => context.Response.WriteAsync("echo"))
                .RequireCors(MyAllowSpecificOrigins);

            endpoints.MapControllers()
                     .RequireCors(MyAllowSpecificOrigins);

            endpoints.MapGet("/echo2",
                context => context.Response.WriteAsync("echo2"));

            endpoints.MapRazorPages();
        });
    }
}

Önceki kodda:

  • app.UseCors CORS ara yazılımını etkinleştirir. Varsayılan ilke yapılandırılmadığından tek app.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 RequireCorsuç 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 Sayfası 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:

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:

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

AllowAnyMethod:

  • 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 WithHeadersbelirtilen ü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-LanguageWithHeadersCORS 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 s ve HTTP kimlik doğrulama düzenlerini içerir cookie. Çıkış noktaları arası bir istekle kimlik bilgilerini göndermek için istemcinin olarak trueayarlanması 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 API'sini kullanma:

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-TypeContent-Languageveya Last-Event-IDdışında Acceptistek ü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 , Hostveya Content-Lengthgibi 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:

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/5uzak 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-Headerstutarlı değildir. Aşağıdakilerden biri varsa:

  • Üst bilgiler, "*"
  • AllowAnyHeader çağrılır: En az Accept, Content-Typeve Originile birlikte, desteklemek istediğiniz özel üst bilgileri ekleyin.

Otomatik denetim öncesi istek kodu

CORS ilkesi aşağıdakilerden biri uygulandığında:

  • içinde Startup.Configurearayarak app.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:
  • 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'nin öncesinde, JSbu kısıtlamayı aşmak için ONP kullanılıyordu. JSONP XHR kullanmaz, yanıtı almak için etiketini kullanır <script> . Betiklerin çıkış noktaları arası yüklenmesine izin verilir.

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 örnekteki PUT test düğmesi

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 bilgileriAccess-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 veya edge://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:

  • adresinde https://cors3.azurewebsites.net/dağıtılan örnek uygulamayı kullanın. Örneği indirmeniz gerekmez.
  • varsayılan URL'sini https://localhost:5001kullanarak örneği ile dotnet run çalıştırın.
  • Url'si https://localhost:44398iç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 ö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);
}

Dağıtılan örneğin test sayfasından önceki kodu test edin. 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