Çıkış Noktası Arası İstekleri (CORS) ASP.NET Core

Rick Anderson ve Rick Larkin

Bu makalede, bir ASP.NET Core uygulamasında CORS'nin nasıl etkinleştir ASP.NET Core açıklanmıştır.

Tarayıcı güvenliği, bir web sayfasının web sayfasına hizmet edenden farklı bir etki alanına istekte bulunarak bunu engellemesini sağlar. Bu kısıtlama, aynı çıkış noktası ilkesi olarak adlandırılan bir kısıtlamadır. Aynı çıkış noktası ilkesi, kötü amaçlı bir sitenin başka bir siteden hassas verileri okumasını önler. Bazen, diğer sitelerin uygulamanıza çıkış noktası arası istekler yapmalarına izin vermek istiyor olabilirsiniz. Daha fazla bilgi için Mozilla CORS makalesine bakın.

Çıkış Noktası Arası Kaynak Paylaşımı (CORS):

  • Bir sunucunun aynı kaynak ilkeyi gevşettiklerine olanak sağlayan bir W3C standardıdır.
  • Bir güvenlik özelliği değildir, CORS güvenliği gevşetir. CORS'ye izin vererek API daha güvenli değildir. Daha fazla bilgi için bkz. CORS nasıl çalışır?
  • Bir sunucunun diğerlerini reddederek çıkış noktası arası isteklere açıkça izin vermesine izin verir.
  • JSONP gibi önceki tekniklerden daha güvenli ve daha esnektir.

Örnek kodu görüntüleme veya indirme ( nasılindir)

Aynı kaynak

İki URL aynı şemalara, konaklara ve bağlantı noktalarına(RFC 6454)sahipse aynı çıkış noktalarına sahiptir.

Bu iki URL aynı çıkış noktasıdır:

  • https://example.com/foo.html
  • https://example.com/bar.html

Bu URL'lerin çıkış noktası önceki iki URL'den farklıdır:

  • https://example.net: Farklı etki alanı
  • https://www.example.com/foo.html: Farklı alt etki alanı
  • http://example.com/foo.html: Farklı dü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ırlamada en ince denetimi sağlar.

Uyarı

UseCors doğru sırayla çağrılmalı. Daha fazla bilgi için bkz. Ara yazılım sırası. Örneğin, UseCors kullanırken önce UseResponseCaching çağrılları UseResponseCaching gerekir.

Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak açıklanmıştır.

Adlandırılmış ilke ve ara yazılım ile CORS

CORS Ara Yazılımı çıkış noktası arası istekleri işler. Aşağıdaki kod, belirtilen kaynaklarla uygulamanın tüm uç noktalarına bir CORS ilkesi uygular:

var  MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

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

// services.AddResponseCaching();

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthorization();

app.MapControllers();

app.Run();

Yukarıdaki kod:

Uç nokta yönlendirme ile CORS ara yazılımı, ve çağrıları arasında yürütülecek şekilde UseRouting UseEndpoints yapılandırıldı.

Önceki koda benzer kodu test etme yönergeleri için bkz. CorS'u test etme.

Yöntem AddCors çağrısı cors hizmetlerini uygulamanın hizmet kapsayıcısı ekler:

var  MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

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

// services.AddResponseCaching();

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthorization();

app.MapControllers();

app.Run();

Daha fazla bilgi için bu belgede CORS ilke seçeneklerine bakın.

Yöntemler, CorsPolicyBuilder aşağıdaki kodda gösterildiği gibi zincirlenmiş olabilir:

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

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

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthorization();

app.MapControllers();

app.Run();

Not: Belirtilen URL,sonda eğik çizgi ( ) / içermemeli. URL ile sonlandırılırsa / karşılaştırma döndürülür ve hiçbir üst bilgi false döndürülmez.

Varsayılan ilke ve ara yazılım ile CORS

Aşağıdaki vurgulanmış kod varsayılan CORS ilkesine olanak sağlar:

var builder = WebApplication.CreateBuilder(args);

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

builder.Services.AddControllers();

var app = builder.Build();

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

app.UseCors();

app.UseAuthorization();

app.MapControllers();

app.Run();

Yukarıdaki kod, tüm denetleyici uç noktalarına varsayılan CORS ilkesi uygular.

Uç nokta yönlendirme ile Cors'u etkinleştirme

kullanarak CORS'nin uç nokta başına temelinde RequireCors etkinleştirilmesi otomatik kontrol öncesi isteklerini desteklemez. Daha fazla bilgi için bu soruna GitHub ve [HttpOptions] ile CORS'u test edin.

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

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

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

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

var app = builder.Build();

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

app.UseCors();

app.UseAuthorization();

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

    endpoints.MapControllers()
             .RequireCors(MyAllowSpecificOrigins);

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

    endpoints.MapRazorPages();
});

app.Run();

Yukarıdaki kodda:

  • app.UseCors CORS ara yazılımlarını sağlar. Varsayılan ilke yapılandırılmamış olduğundan tek app.UseCors() başına CORS'yi etkinleştirmez.
  • ve /echo denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin sağlar.
  • Ve /echo2 Sayfaları Razor uç noktaları, varsayılan ilke belirtilmedikten çıkış noktaları arası isteklere izin vermez.

[DisableCors] özniteliği ile uç nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı RequireCors bırakmaz.

Yukarıdakine benzer kodu test etme yönergeleri için bkz. Uç nokta yönlendirme ile CORS'u test etme ve [HttpOptions] .

Özniteliklerle CORS'yi etkinleştirme

[EnableCors] özniteliğiyle CORS'yi etkinleştirme ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulama en ince denetimi sağlar.

[EnableCors] özniteliği CORS'yi genel olarak uygulamaya alternatif sağlar. özniteliği, [EnableCors] tüm uç noktalar yerine seçilen uç noktalar için CORS'ye olanak sağlar:

  • [EnableCors] varsayılan ilkeyi belirtir.
  • [EnableCors("{Policy String}")] adlandırılmış bir ilke belirtir.

Özniteliği [EnableCors] aşağıdakilere uygulanabilir:

  • Razor Sayfası PageModel
  • Denetleyici
  • Denetleyici eylemi yöntemi

Denetleyicilere, sayfa modellere veya özniteliğine sahip eylem yöntemlerine farklı ilkeler [EnableCors] uygulanabilir. Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve CORS ara [EnableCors] yazılımda etkinleştirildiğinde her iki ilke de uygulanır. İlkeleri birleştirmenizi öneririz. Aynı uygulamada [EnableCors] değil özniteliğini veya ara yazılımı kullanın.

Aşağıdaki kod her yönteme farklı bir ilke uygular:

[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
    // GET api/values
    [EnableCors("AnotherPolicy")]
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "green widget", "red widget" };
    }

    // GET api/values/5
    [EnableCors("Policy1")]
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return id switch
        {
            1 => "green widget",
            2 => "red widget",
            _ => NotFound(),
        };
    }
}

Aşağıdaki kod iki CORS ilkeleri oluşturur:

var builder = WebApplication.CreateBuilder(args);

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

    options.AddPolicy("AnotherPolicy",
        builder =>
        {
            builder.WithOrigins("http://www.contoso.com")
                                .AllowAnyHeader()
                                .AllowAnyMethod();
        });
});

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseRouting();

app.UseCors();

app.UseAuthorization();

app.MapControllers();

app.Run();

CORS isteklerini sınırlamak için en ince denetim için:

  • Adlandırılmış [EnableCors("MyPolicy")] bir ilke ile kullanın.
  • Varsayılan ilkeyi tanımlamayın.
  • Uç nokta yönlendirmeyi kullanmayın.

Sonraki bölümde yer alan kod yukarıdaki listeyi karşılar.

Önceki koda benzer kodu test etme yönergeleri için bkz. CorS'u test etme.

CORS'yi devre dışı bırakma

[DisableCors] özniteliği,nokta yönlendirmesi tarafından etkinleştirilen CORS'yi devre dışı bırakmaz.

Aşağıdaki kod CORS ilkesi "MyPolicy" tanımlar:

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "MyPolicy",
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com")
                    .WithMethods("PUT", "DELETE", "GET");
        });
});

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

var app = builder.Build();

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

app.UseCors();

app.UseAuthorization();

app.MapControllers();
app.MapRazorPages();

app.Run();

Aşağıdaki kod eylem için CORS'yi devre dışı GetValues2 bıraktır:

[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public IActionResult Get() =>
        ControllerContext.MyDisplayRouteInfo();

    // GET api/values/5
    [HttpGet("{id}")]
    public IActionResult Get(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // PUT api/values/5
    [HttpPut("{id}")]
    public IActionResult Put(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);


    // GET: api/values/GetValues2
    [DisableCors]
    [HttpGet("{action}")]
    public IActionResult GetValues2() =>
        ControllerContext.MyDisplayRouteInfo();

}

Yukarıdaki kod:

Önceki kodun test edilmesine ilişkin yönergeler için bkz. Test CORS .

CORS ilke seçenekleri

Bu bölümde, bir CORS ilkesinde ayarlanmakta olabilecek çeşitli seçenekler açıklanmaktadır:

AddPolicyprogram. cs' de çağrılır. Bazı seçenekler için, ilk olarak CORS 'Nin nasıl çalıştığı bölümü okumanız yararlı olabilir.

İzin verilen kaynakları ayarla

AllowAnyOrigin: Herhangi bir düzen (veya) ile tüm kaynaklardan gelen CORS isteklerine izin verir http https . AllowAnyOrigin , herhangi bir Web sitesi uygulamaya çapraz kaynak istekleri yapabildiğinden güvenli değildir.

Not

AllowAnyOriginVe AllowCredentials güvenli olmayan bir yapılandırma belirtip, siteler arası istek sahteciliği ile sonuçlanabilir. Bir uygulama her iki yöntemle yapılandırıldığında, CORS hizmeti geçersiz bir CORS yanıtı döndürür.

AllowAnyOrigin ön kontrol isteklerini ve Access-Control-Allow-Origin üstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.

SetIsOriginAllowedToAllowWildcardSubdomains: IsOriginAllowed Kaynağa izin verilip verilmediğini değerlendirirken, kaynağın yapılandırılmış bir joker karakterle eşleşmesini sağlayan bir işlev olarak ilkenin özelliğini ayarlar.

var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("https://*.example.com")
                .SetIsOriginAllowedToAllowWildcardSubdomains();
        });
});

builder.Services.AddControllers();

var app = builder.Build();

İzin verilen HTTP yöntemlerini ayarlama

AllowAnyMethod:

  • Herhangi bir HTTP yöntemine izin verir:
  • Ön kontrol isteklerini ve Access-Control-Allow-Methods üstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.

İzin verilen istek üst bilgilerini ayarlama

Belirli başlıkların, Yazar isteği üstbilgileriADLı bir CORS isteğinde gönderilmesine izin vermek için, ' i çağırın WithHeaders ve izin verilen üst bilgileri belirtin:

using Microsoft.Net.Http.Headers;

var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
       builder =>
       {
           builder.WithOrigins("http://example.com")
                  .WithHeaders(HeaderNames.ContentType, "x-custom-header");
       });
});

builder.Services.AddControllers();

var app = builder.Build();

Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın AllowAnyHeader :

var MyAllowSpecificOrigins = "_MyAllowSubdomainPolicy";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("https://*.example.com")
                   .AllowAnyHeader();
        });
});

builder.Services.AddControllers();

var app = builder.Build();

AllowAnyHeader ön kontrol isteklerini ve erişim-denetim-istek-üst bilgi üst bilgisini etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.

Tarafından belirtilen belirli başlıklarıyla eşleşen bir CORS ara yazılım ilkesi, WithHeaders yalnızca Access-Control-Request-Headers ' de belirtilen üstbilgiler ile tam olarak eşleşiyorsa mümkündür WithHeaders .

Örneğin, aşağıdaki gibi yapılandırılmış bir uygulamayı göz önünde bulundurun:

app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));

CORS ara yazılımı, Content-Language (headernames. contentlanguage) içinde listelenmediği için aşağıdaki istek üst bilgisi ile bir ön denetim isteğini reddettiğinde WithHeaders :

Access-Control-Request-Headers: Cache-Control, Content-Language

Uygulama 200 ok yanıtı DÖNDÜRÜYOR ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez.

Gösterilen yanıt üst bilgilerini ayarlama

Varsayılan olarak tarayıcı, tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz. W3C çıkış noktaları arası kaynak paylaşımı (terminoloji): basit yanıt üst bilgisi.

Varsayılan olarak kullanılabilen yanıt üstbilgileri şunlardır:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

CORS belirtimi, bu üst bilgiler basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulama için kullanılabilir hale getirmek için şunu çağırın WithExposedHeaders :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("MyExposeResponseHeadersPolicy",
        builder =>
        {
            builder.WithOrigins("https://*.example.com")
                   .WithExposedHeaders("x-custom-header");
        });
});

builder.Services.AddControllers();

var app = builder.Build();

Kaynaklar arası isteklerde kimlik bilgileri

Kimlik bilgileri CORS isteğinde özel işleme gerektirir. Varsayılan olarak tarayıcı, kimlik bilgilerini bir çapraz kaynak isteğiyle göndermez. Kimlik bilgileri cookie , s ve http kimlik doğrulama düzenlerini içerir. Bir çapraz kaynak isteğiyle kimlik bilgilerini göndermek için, istemcisinin olarak ayarlanması gerekir XMLHttpRequest.withCredentials true .

XMLHttpRequestDoğrudan kullanarak:

var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;

JQuery kullanarak:

$.ajax({
  type: 'get',
  url: 'https://www.example.com/api/test',
  xhrFields: {
    withCredentials: true
  }
});

Fetch API'sini kullanma:

fetch('https://www.example.com/api/test', {
    credentials: 'include'
});

Sunucu kimlik bilgilerine izin vermelidir. Çıkış noktaları arası kimlik bilgilerine izin vermek için şunu arayın AllowCredentials :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("MyMyAllowCredentialsPolicy",
        builder =>
        {
            builder.WithOrigins("http://example.com")
                   .AllowCredentials();
        });
});

builder.Services.AddControllers();

var app = builder.Build();

HTTP yanıtı, Access-Control-Allow-Credentials tarayıcıya sunucunun bir çapraz kaynak isteği için kimlik bilgileri verdiğini bildiren bir üst bilgi içerir.

Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli bir Access-Control-Allow-Credentials üst bilgi içermiyorsa, tarayıcı uygulamaya yanıtı kullanıma sunmaz ve çapraz kaynak isteği başarısız olur.

Çıkış noktaları arası kimlik bilgilerine izin vermek bir güvenlik riskidir. Başka bir etki alanındaki Web sitesi, kullanıcının bilgisi olmadan kullanıcı adına, oturum açmış bir kullanıcının kimlik bilgilerini uygulamaya gönderebilir.

CORS belirtimi Ayrıca "*" üst bilgi varsa, çıkış (tüm kaynaklar) ayarının geçersiz olduğunu belirtir Access-Control-Allow-Credentials .

Ön kontrol istekleri

Bazı CORS istekleri için, tarayıcı gerçek isteği yapmadan önce ek bir seçenek isteği gönderir. Bu isteğe bir ön kontrol isteğidenir. Aşağıdaki koşulların Tümü doğruysa tarayıcı, ön kontrol isteğini atlayabilir:

  • İstek yöntemi al, HEAD veya POST.
  • Uygulama,,, veya dışındaki istek üst bilgilerini ayarlanmamış Accept Accept-Language Content-Language Content-Type Last-Event-ID .
  • , Content-Type Ayarlandıysa, aşağıdaki değerlerden birine sahip olan üst bilgi:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

İstemci isteği için ayarlanan istek üst bilgileri kuralı, uygulamanın, nesne üzerinde çağırarak ayarladığı üst bilgiler için geçerlidir setRequestHeader XMLHttpRequest . CORS belirtimi, bu üst bilgiler Yazar istek üst bilgileriniçağırır. Kural,, veya gibi tarayıcının ayarlayabilmesi için, veya gibi bir üst bilgiye uygulanmaz User-Agent Host Content-Length .

Aşağıda, bu belgenin Test CORS bölümündeki [testi koy] düğmesinden yapılmış olan ön kontrol isteğine benzer bir yanıt verilmiştir.

General:
Request URL: https://cors3.azurewebsites.net/api/values/5
Request Method: OPTIONS
Status Code: 204 No Content

Response Headers:
Access-Control-Allow-Methods: PUT,DELETE,GET
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f8...8;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Vary: Origin

Request Headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Method: PUT
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0

Ön kontrol isteği http seçenekleri yöntemini kullanır. Aşağıdaki üstbilgiler bulunabilir:

Ön kontrol isteği reddedilirse, uygulama bir 200 OK yanıt döndürür ancak CORS üst bilgilerini yapmaz. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez. Reddedilen bir ön kontrol isteğine bir örnek için, bu belgenin Test CORS bölümüne bakın.

Konsol uygulaması, F12 araçlarını kullanarak tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:

  • Firefox: çapraz kaynak Isteği engellendi: aynı kaynak Ilkesi, konumundaki uzak kaynağı okumaktan izin vermez https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 . (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi
  • Chromium tabanlı: ' ' kaynağından ' ' konumundaki getirme erişimi https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 https://cors3.azurewebsites.net CORS ilkesi tarafından engellendi: ön kontrol isteğine verilen yanıt erişim denetimi denetimine geçti: istenen kaynakta ' erişim-control-Allow-origin ' üst bilgisi yok. Donuk bir yanıt ihtiyaçlarınıza hizmet veriyorsa, isteği CORS devre dışı olarak getirmek için isteğin modunu ' No-CORS ' olarak ayarlayın.

Belirli üstbilgilere izin vermek için şunu arayın WithHeaders :

using Microsoft.Net.Http.Headers;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("MyAllowHeadersPolicy",
        builder =>
        {
        builder.WithOrigins("http://example.com")
                   .WithHeaders(HeaderNames.ContentType, "x-custom-header");
        });
});

builder.Services.AddControllers();

var app = builder.Build();

Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın AllowAnyHeader :

using Microsoft.Net.Http.Headers;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("MyAllowAllHeadersPolicy",
        builder =>
        {
            builder.WithOrigins("https://*.example.com")
                   .AllowAnyHeader();
        });
});

builder.Services.AddControllers();

var app = builder.Build();

Tarayıcılar, nasıl ayarlandıklarından tutarlı değildir Access-Control-Request-Headers . Aşağıdakilerden biri:

  • Üst bilgiler, dışında bir şeye ayarlanır "*"
  • AllowAnyHeader çağrıldı: en az Accept , Content-Type , ve, ve Origin desteklemek istediğiniz tüm özel üstbilgileri ekleyin.

Otomatik ön kontrol istek kodu

CORS ilkesi uygulandığında:

  • app.UseCors Program. cs' de çağırarak Global olarak.
  • Özniteliği kullanılıyor [EnableCors] .

ASP.NET Core, ön kontrol seçenekleri isteğine yanıt verir.

Şu anda bir uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleri desteklenmez.

Bu belgenin Test CORS bölümü bu davranışı gösterir.

[HttpOptions] ön kontrol istekleri için öznitelik

cors uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle cors ön denetim isteklerini otomatik olarak yanıtlar. Bazı senaryolarda bu durum olmayabilir. Örneğin, uç nokta yönlendirme Ile CORS'yi kullanma.

Aşağıdaki kod, Seçenekler istekleri için uç noktalar oluşturmak için [HttpOptions] özniteliğini kullanır:

[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
    // OPTIONS: api/TodoItems2/5
    [HttpOptions("{id}")]
    public IActionResult PreflightRoute(int id)
    {
        return NoContent();
    }

    // OPTIONS: api/TodoItems2 
    [HttpOptions]
    public IActionResult PreflightRoute()
    {
        return NoContent();
    }

    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return BadRequest();
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

Önceki kodun test edilmesine ilişkin yönergeler için bkz. Endpoint Routing Ile test CORS ve [HttpOptions] .

Ön kontrol sona erme süresini ayarlama

Access-Control-Max-AgeÜst bilgi, ön kontrol isteğine olan yanıtın ne kadar süreyle önbelleğe alınacağını belirtir. Bu üstbilgiyi ayarlamak için şunu arayın SetPreflightMaxAge :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("MySetPreflightExpirationPolicy",
        builder =>
        {
            builder.WithOrigins("http://example.com")
                   .SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
        });
});

builder.Services.AddControllers();

var app = builder.Build();

CORS nasıl kullanılır?

Bu bölümde, HTTP iletileri düzeyindeki bir CORS isteğinde ne olacağı açıklanmaktadır.

  • CORS bir güvenlik özelliği değil . CORS, bir sunucunun aynı kaynaklı ilkeyi rahat bir şekilde sağlamasına izin veren bir W3C standardıdır.
    • Örneğin, kötü niyetli bir aktör sitenize karşı siteler arası komut dosyası (XSS) kullanabilir ve bilgileri çalmak için CORS özellikli sitesine bir siteler arası istek yürütebilir.
  • Bir API, CORS 'ye izin vererek daha güvenli değildir.
    • CORS 'yi zorlamak için istemciye (tarayıcı) sahiptir. Sunucu isteği yürütür ve yanıtı döndürür. Bu, bir hatayı döndüren ve yanıtı engelleyen istemcdir. Örneğin, aşağıdaki araçlardan herhangi birinde sunucu yanıtı görüntülenir:
  • Bir sunucu, tarayıcıların çapraz kaynak XHR veya Fetch API isteği çalıştırmasına izin vermesinin yasaktır bir yoludur.
    • CORS içermeyen tarayıcılar, çıkış noktaları arası istekleri yapamıyor. CORS 'den önce, bu kısıtlamayı aşmak için JSONP kullanılmıştır. JSONP XHR kullanmaz, <script> yanıtı almak için etiketini kullanır. Betiklerin, çapraz kaynak olarak yüklenmesine izin verilir.

CORS belirtimi , çıkış noktaları arası istekleri etkinleştiren bırkaç yeni http üst bilgisi sunmuştur. Bir tarayıcı CORS 'yi destekliyorsa, bu üst bilgileri, çıkış noktaları arası istekler için otomatik olarak ayarlar. CORS 'yi etkinleştirmek için özel JavaScript kodu gerekli değildir.

Dağıtılan örnekteki testi Yerleştir düğmesi

Aşağıda, Values test düğmesinden olan bir çapraz kaynak isteğine bir örnek verilmiştir https://cors1.azurewebsites.net/api/values . OriginÜst bilgi:

  • , İsteği yapan sitenin etki alanını sağlar.
  • Gereklidir ve konaktan farklı olmalıdır.

Genel üstbilgiler

Request URL: https://cors1.azurewebsites.net/api/values
Request Method: GET
Status Code: 200 OK

Yanıt üst bilgileri

Content-Encoding: gzip
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Powered-By: ASP.NET

İstek üst bilgileri

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: cors1.azurewebsites.net
Origin: https://cors3.azurewebsites.net
Referer: https://cors3.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 ...

OPTIONSİsteklerde, sunucu yanıtta yanıt üstbilgileri Access-Control-Allow-Origin: {allowed origin} üst bilgisini ayarlar. Örneğin, dağıtılan örnek, delete [enablecors] düğme OPTIONS isteği aşağıdaki üstbilgileri içerir:

Genel üstbilgiler

Request URL: https://cors3.azurewebsites.net/api/TodoItems2/MyDelete2/5
Request Method: OPTIONS
Status Code: 204 No Content

Yanıt üst bilgileri

Access-Control-Allow-Headers: Content-Type,x-custom-header
Access-Control-Allow-Methods: PUT,DELETE,GET,OPTIONS
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors3.azurewebsites.net
Vary: Origin
X-Powered-By: ASP.NET

İstek üst bilgileri

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: DELETE
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/test?number=2
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0

Önceki yanıt üst bilgilerinde sunucu, yanıtta Access-Control-Allow-Origin üst bilgisini ayarlar. https://cors1.azurewebsites.netBu üstbilginin değeri, Origin istekten gelen üstbilgiyle eşleşir.

AllowAnyOriginÇağrılırsa, Access-Control-Allow-Origin: * joker karakter değeri döndürülür. AllowAnyOrigin Tüm kaynağa izin verir.

Yanıt Access-Control-Allow-Origin üstbilgiyi içermiyorsa, çapraz kaynak isteği başarısız olur. Özellikle, tarayıcı isteğe izin vermez. Sunucu başarılı bir yanıt döndürse bile tarayıcı, yanıtı istemci uygulama için kullanılabilir hale getirir.

Görüntüleme SEÇENEKLERI istekleri

Varsayılan olarak, Chrome ve Edge tarayıcıları, F12 araçlarının Ağ sekmesinde seçenek isteklerini göstermez. Bu tarayıcılarda seçenek isteklerini göstermek için:

  • chrome://flags/#out-of-blink-cors veya edge://flags/#out-of-blink-cors
  • bayrağı devre dışı bırakın.
  • uygulamasını.

Firefox, varsayılan olarak seçenek isteklerini gösterir.

IIS 'de CORS

ııs 'e dağıtım yaparken, sunucu anonim erişime izin verecek şekilde yapılandırılmamışsa CORS Windows kimlik doğrulamasından önce çalışmalıdır. Bu senaryoyu desteklemek için, IIS CORS modülünün uygulama için yüklenmiş ve yapılandırılmış olması gerekir.

Test CORS

Örnek indirme , CORS 'yi test etmek için kod içerir. Bkz. indirme. Örnek, eklenen sayfaların bulunduğu bir API projem örneğidir Razor :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                        "http://www.contoso.com",
                        "https://cors1.azurewebsites.net",
                        "https://cors3.azurewebsites.net",
                        "https://localhost:44398",
                        "https://localhost:5001")
                            .WithMethods("PUT", "DELETE", "GET");
                });
});

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

var app = builder.Build();

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

app.UseCors();

app.UseAuthorization();

app.MapControllers();
app.MapRazorPages();

app.Run();

Uyarı

WithOrigins("https://localhost:<port>"); yalnızca indirme örnek kodunabenzer bir örnek uygulamanın test edilmesi için kullanılmalıdır.

Aşağıdakiler, ValuesController test için uç noktaları sağlar:

[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public IActionResult Get() =>
        ControllerContext.MyDisplayRouteInfo();

    // GET api/values/5
    [HttpGet("{id}")]
    public IActionResult Get(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // PUT api/values/5
    [HttpPut("{id}")]
    public IActionResult Put(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);


    // GET: api/values/GetValues2
    [DisableCors]
    [HttpGet("{action}")]
    public IActionResult GetValues2() =>
        ControllerContext.MyDisplayRouteInfo();

}

mydisplayrouteınfo , Rick. Docs. Samples. routeınfo NuGet paketi tarafından sağlanır ve rota bilgilerini görüntüler.

Aşağıdaki yaklaşımlardan birini kullanarak önceki örnek kodu test edin:

  • Üzerinde dağıtılan örnek uygulamayı kullanın https://cors3.azurewebsites.net/ . Örneği indirmeniz gerekmez.
  • dotnet runVarsayılan URL 'sini kullanarak örneği çalıştırın https://localhost:5001 .
  • bir URL 'si için bağlantı noktası 44398 olarak ayarlanan Visual Studio örneği çalıştırın https://localhost:44398 .

F12 araçlarıyla bir tarayıcı kullanma:

  • Değerler düğmesini seçin ve sekmesindeki üst bilgileri gözden geçirin.

  • Testi yerleştir düğmesini seçin. Seçenekler isteği görüntüleme yönergeleri için bkz. görüntüleme seçenekleri istekleri . PUT testi iki istek, bir seçenekler ön hazırlığı ISTEğI ve PUT isteği oluşturur.

  • GetValues2 [DisableCors] Başarısız BIR CORS isteğini tetiklemek için düğmeyi seçin. Belgede bahsedildiği gibi, yanıt 200 başarılı döndürür, ancak CORS isteği yapılmaz. CORS hatasını görmek için konsol sekmesini seçin. Tarayıcıya bağlı olarak aşağıdakine benzer bir hata görüntülenir:

    'https://cors1.azurewebsites.net/api/values/GetValues2'Kaynak kimden kaynağı 'https://cors3.azurewebsites.net' CORS ilkesi tarafından engellendi: İstenen kaynakta ' erişim-denetim-Izin-Origin ' üst bilgisi yok. Donuk bir yanıt ihtiyaçlarınıza hizmet veriyorsa, isteği CORS devre dışı olarak getirmek için isteğin modunu ' No-CORS ' olarak ayarlayın.

CORS özellikli uç noktalar, kıvrımlı, Fiddlerveya Postmangibi bir araçla test edilebilir. Bir araç kullanırken, üst bilgi tarafından belirtilen isteğin kaynağı Origin isteği alan konaktan farklı olmalıdır. İstek, üst bilgi değerine göre Çıkış dışı değilse Origin :

  • CORS ara yazılımı için isteği işleme gereksinimi yoktur.
  • CORS üstbilgileri yanıtta döndürülmedi.

Aşağıdaki komut, curl bilgileri içeren BIR seçenek isteği vermek için kullanır:

curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i

ENDPOINT yönlendirme ve [HttpOptions] ile test CORS

Şu anda bir uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleri desteklenmez . CORS 'yi etkinleştirmek için Endpoint Routingkullanan aşağıdaki kodu göz önünde bulundurun:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                        "http://www.contoso.com",
                        "https://cors1.azurewebsites.net",
                        "https://cors3.azurewebsites.net",
                        "https://localhost:44398",
                        "https://localhost:5001")
                            .WithMethods("PUT", "DELETE", "GET");
                });
});

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

var app = builder.Build();

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

app.UseCors();

app.UseAuthorization();

app.MapControllers();
app.MapRazorPages();

app.Run();

Aşağıdakiler TodoItems1Controller test için uç noktalar sağlar:

[Route("api/[controller]")]
[ApiController]
public class TodoItems1Controller : ControllerBase
{
    // PUT: api/TodoItems1/5
    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return Content($"ID = {id}");
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // Delete: api/TodoItems1/5
    [HttpDelete("{id}")]
    public IActionResult MyDelete(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // GET: api/TodoItems1
    [HttpGet]
    public IActionResult GetTodoItems() =>
        ControllerContext.MyDisplayRouteInfo();

    [EnableCors]
    [HttpGet("{action}")]
    public IActionResult GetTodoItems2() =>
        ControllerContext.MyDisplayRouteInfo();

    // Delete: api/TodoItems1/MyDelete2/5
    [EnableCors]
    [HttpDelete("{action}/{id}")]
    public IActionResult MyDelete2(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);
}

Önceki kodu dağıtılan Örneğin Test sayfasından test edin.

Bitiş noktaları, ön kontrol isteklerini içerdiğinden ve yanıt verdiği için delete [enablecors] ve Get [enablecors] düğmeleri başarılı olur [EnableCors] . Diğer uç noktalar başarısız olur. JavaScript şu şekilde gönderdiği için Al düğmesi başarısız olur:

 headers: {
      "Content-Type": "x-custom-header"
 },

Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak seçenek isteklerine yanıt vermek için açık kod içerir:

[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
    // OPTIONS: api/TodoItems2/5
    [HttpOptions("{id}")]
    public IActionResult PreflightRoute(int id)
    {
        return NoContent();
    }

    // OPTIONS: api/TodoItems2 
    [HttpOptions]
    public IActionResult PreflightRoute()
    {
        return NoContent();
    }

    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return BadRequest();
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // [EnableCors] // Not needed as OPTIONS path provided
    [HttpDelete("{id}")]
    public IActionResult MyDelete(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    [EnableCors]  // Rquired for this path
    [HttpGet]
    public IActionResult GetTodoItems() =>
        ControllerContext.MyDisplayRouteInfo();

    [HttpGet("{action}")]
    public IActionResult GetTodoItems2() =>
        ControllerContext.MyDisplayRouteInfo();

    [EnableCors]  // Rquired for this path
    [HttpDelete("{action}/{id}")]
    public IActionResult MyDelete2(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);
}

Önceki kodu dağıtılan örneğin Test sayfasından test edin. Denetleyici açılan listesinde, ön kontrol ' yı ve ardından denetleyiciyi ayarla' yı seçin. Uç noktalara yönelik tüm CORS çağrıları TodoItems2Controller başarılı olur.

Ek kaynaklar

Tarafından Rick Anderson ve Kirk larkabağı

bu makalede, ASP.NET Core uygulamasında CORS 'nin nasıl etkinleştirileceği gösterilmektedir.

Tarayıcı güvenliği, bir Web sayfasının Web sayfasını sunduğundan farklı bir etki alanına istek yapmasını engeller. Bu kısıtlamaya aynı-Origin ilkesi adı verilir. Aynı-kaynak ilkesi, kötü niyetli bir sitenin gizli verileri başka bir siteden okumasını engeller. Bazen diğer sitelerin uygulamanıza çapraz çıkış istekleri yapmasına izin vermek isteyebilirsiniz. Daha fazla bilgi için bkz. MOZILLA CORS makalesi.

Çapraz kaynak kaynak paylaşımı (CORS):

  • , Bir sunucunun aynı kaynak ilkeyi rahat bir şekilde sağlamasına izin veren bir W3C standardıdır.
  • Güvenlik özelliği değil , CORS güvenliği. CORS 'nin izin vermesini sağlayan bir API daha güvenli değildir. Daha fazla bilgi için bkz. CORS çalışma.
  • Bir sunucunun bazı çapraz kaynak isteklerine, diğerlerini reddetirken açık olarak izin almasına izin verir.
  • , JSONPgibi önceki tekniklerin daha güvenli ve daha esnektir.

Örnek kodu görüntüleme veya indirme (nasıl indirileceği)

Aynı kaynak

Özdeş şemaları, konakları ve bağlantı noktalarına sahip olmaları durumunda iki URL aynı kaynağa sahiptir (RFC 6454).

Bu iki URL aynı kaynağa sahiptir:

  • https://example.com/foo.html
  • https://example.com/bar.html

Bu URL 'Ler, önceki iki URL 'den farklı kaynaklardan farklıdır:

  • https://example.net: Farklı etki alanı
  • https://www.example.com/foo.html: Farklı alt etki alanı
  • http://example.com/foo.html: Farklı düzen
  • https://example.com:9000/foo.html: Farklı bağlantı noktası

CORS'yi etkinleştirme

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

Adlandırılmış ilkeyle [Enablecors] ÖZNITELIĞINI kullanmak CORS 'yi destekleyen uç noktaları sınırlayan en yoğun denetimi sağlar.

Uyarı

UseCors doğru sırada çağrılmalıdır. Daha fazla bilgi için bkz. Ara yazılım sırası. Örneğin, kullanılmadan UseCors önce çağrılmalıdır UseResponseCaching UseResponseCaching .

Her yaklaşım aşağıdaki bölümlerde ayrıntılı olarak verilmiştir.

Adlandırılmış ilke ve ara yazılım ile CORS

CORS ara yazılımı, çıkış noktaları arası istekleri işler. Aşağıdaki kod, belirtilen kaynakları kullanarak tüm uygulamanın uç noktalarına bir CORS ilkesi uygular:

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

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

        // services.AddResponseCaching();
        services.AddControllers();
    }

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

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

        app.UseCors(MyAllowSpecificOrigins);

        // app.UseResponseCaching();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

Yukarıdaki kod:

Endpoint Routing ile CORS ara yazılımı , ve çağrıları arasında yürütülecek şekilde yapılandırılmalıdır UseRouting UseEndpoints .

Yukarıdaki koda benzer test kodu hakkında yönergeler için bkz. Test CORS .

AddCorsYöntem çağrısı, uygulamanın hizmet KAPSAYıCıSıNA CORS Hizmetleri ekler:

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

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

        // services.AddResponseCaching();
        services.AddControllers();
    }

Daha fazla bilgi için bu belgedeki CORS ilke seçenekleri bölümüne bakın.

CorsPolicyBuilderYöntemler aşağıdaki kodda gösterildiği gibi zincirleme olabilir:

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

    services.AddControllers();
}

Not: belirtilen URL sonunda eğik çizgi ( / ) içermemelidir. URL ile sonlandığında / karşılaştırma döndürülür false ve üst bilgi döndürülmez.

Varsayılan ilke ve ara yazılım ile CORS

Aşağıdaki vurgulanan kod varsayılan CORS ilkesini sunar:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddDefaultPolicy(
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com");
                });
        });

        services.AddControllers();
    }

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

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

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

Yukarıdaki kod, tüm denetleyici uç noktalarına varsayılan CORS ilkesini uygular.

Uç nokta yönlendirme ile CORS 'yi etkinleştirme

İle uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleridesteklenmez. daha fazla bilgi için bkz. bu GitHub sorun ve Test no endpoint routing ve [HttpOptions].

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

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

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

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

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

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

        app.UseCors();

        app.UseAuthorization();

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

            endpoints.MapControllers()
                     .RequireCors(MyAllowSpecificOrigins);

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

            endpoints.MapRazorPages();
        });
    }
}

Yukarıdaki kodda:

  • app.UseCors CORS ara yazılımını sunar. Varsayılan bir ilke yapılandırılmadığından, app.UseCors() tek BAŞıNA CORS 'yi etkinleştirmeyin.
  • /echoVe denetleyici uç noktaları, belirtilen ilkeyi kullanarak çıkış noktaları arası isteklere izin verir.
  • /echo2 Razor Varsayılan ilke belirtilmediğinden ve sayfa uç noktaları, çıkış noktaları arası isteklere izin vermez .

[Disablecors] özniteliği, ile Endpoint Routing tarafından etkinleştirilen CORS 'yi devre dışı bırakmıyor RequireCors .

Yukarıdaki koda benzer test kodu hakkında yönergeler için bkz. Endpoint Routing Ile test CORS ve [HttpOptions] .

CORS 'yi özniteliklerle etkinleştir

CORS 'yi [Enablecors] özniteliğiyle etkinleştirmek ve yalnızca CORS gerektiren uç noktalara adlandırılmış bir ilke uygulamak, en derin denetimi sağlar.

[Enablecors] ÖZNITELIĞI, CORS 'yi küresel olarak uygulamaya bir alternatif sağlar. [EnableCors]Öznitelik, tüm uç noktalar yerine seçili uç noktalar IÇIN CORS 'yi sunar:

  • [EnableCors] varsayılan ilkeyi belirtir.
  • [EnableCors("{Policy String}")] adlandırılmış bir ilke belirtir.

[EnableCors]Özniteliği öğesine uygulanabilir:

  • Razor Sayfasında PageModel
  • Denetleyici
  • Denetleyici eylemi yöntemi

Öznitelikleri olan denetleyicilere, sayfa modellerine veya eylem yöntemlerine farklı ilkeler uygulanabilir [EnableCors] . [EnableCors]Öznitelik bir denetleyiciye, sayfa modeline veya eylem yöntemine uygulandığında ve bir ara yazılım IÇINDE CORS etkinleştirildiğinde, her iki ilke de uygulanır. İlkelerin birleştirilmesi önerilir. [EnableCors] Aynı uygulamada değil, özniteliğini veya ara yazılımını kullanın.

Aşağıdaki kod her bir yönteme farklı bir ilke uygular:

[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
    // GET api/values
    [EnableCors("AnotherPolicy")]
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "green widget", "red widget" };
    }

    // GET api/values/5
    [EnableCors("Policy1")]
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return id switch
        {
            1 => "green widget",
            2 => "red widget",
            _ => NotFound(),
        };
    }
}

Aşağıdaki kod iki CORS ilkesi oluşturur:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

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

            options.AddPolicy("AnotherPolicy",
                builder =>
                {
                    builder.WithOrigins("http://www.contoso.com")
                                        .AllowAnyHeader()
                                        .AllowAnyMethod();
                });
        });

        services.AddControllers();
    }

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

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

CORS isteklerini sınırlayan en yoğun denetim için:

  • [EnableCors("MyPolicy")]Adlandırılmış ilkeyle kullanın.
  • Varsayılan bir ilke tanımlamayın.
  • Endpoint Routingkullanmayın.

Sonraki bölümdeki kod, önceki listeyi karşılar.

Yukarıdaki koda benzer test kodu hakkında yönergeler için bkz. Test CORS .

CORS 'yi devre dışı bırak

[Disablecors] özniteliği Endpoint ROUTINGtarafından etkinleştirilen CORS 'yi devre dışı bırakmıyor .

Aşağıdaki kod CORS ilkesini tanımlar "MyPolicy" :

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com")
                            .WithMethods("PUT", "DELETE", "GET");
                });
        });

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

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

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

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapRazorPages();
        });
    }
}

Aşağıdaki kod, eylem için CORS 'yi devre dışı bırakır GetValues2 :

[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public IActionResult Get() =>
        ControllerContext.MyDisplayRouteInfo();

    // GET api/values/5
    [HttpGet("{id}")]
    public IActionResult Get(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // PUT api/values/5
    [HttpPut("{id}")]
    public IActionResult Put(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);


    // GET: api/values/GetValues2
    [DisableCors]
    [HttpGet("{action}")]
    public IActionResult GetValues2() =>
        ControllerContext.MyDisplayRouteInfo();

}

Yukarıdaki kod:

Önceki kodun test edilmesine ilişkin yönergeler için bkz. Test CORS .

CORS ilke seçenekleri

Bu bölümde, bir CORS ilkesinde ayarlanmakta olabilecek çeşitli seçenekler açıklanmaktadır:

AddPolicy içinde çağırılır Startup.ConfigureServices . Bazı seçenekler için, ilk olarak CORS 'Nin nasıl çalıştığı bölümü okumanız yararlı olabilir.

İzin verilen kaynakları ayarla

AllowAnyOrigin: Herhangi bir düzen (veya) ile tüm kaynaklardan gelen CORS isteklerine izin verir http https . AllowAnyOrigin , herhangi bir Web sitesi uygulamaya çapraz kaynak istekleri yapabildiğinden güvenli değildir.

Not

AllowAnyOriginVe AllowCredentials güvenli olmayan bir yapılandırma belirtip, siteler arası istek sahteciliği ile sonuçlanabilir. Bir uygulama her iki yöntemle yapılandırıldığında, CORS hizmeti geçersiz bir CORS yanıtı döndürür.

AllowAnyOrigin ön kontrol isteklerini ve Access-Control-Allow-Origin üstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.

SetIsOriginAllowedToAllowWildcardSubdomains: IsOriginAllowed Kaynağa izin verilip verilmediğini değerlendirirken, kaynağın yapılandırılmış bir joker karakterle eşleşmesini sağlayan bir işlev olarak ilkenin özelliğini ayarlar.

options.AddPolicy("MyAllowSubdomainPolicy",
    builder =>
    {
        builder.WithOrigins("https://*.example.com")
            .SetIsOriginAllowedToAllowWildcardSubdomains();
    });

İzin verilen HTTP yöntemlerini ayarlama

AllowAnyMethod:

  • Herhangi bir HTTP yöntemine izin verir:
  • Ön kontrol isteklerini ve Access-Control-Allow-Methods üstbilgiyi etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.

İzin verilen istek üst bilgilerini ayarlama

Belirli başlıkların, Yazar isteği üstbilgileriADLı bir CORS isteğinde gönderilmesine izin vermek için, ' i çağırın WithHeaders ve izin verilen üst bilgileri belirtin:

options.AddPolicy("MyAllowHeadersPolicy",
    builder =>
    {
        // requires using Microsoft.Net.Http.Headers;
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın AllowAnyHeader :

options.AddPolicy("MyAllowAllHeadersPolicy",
    builder =>
    {
        builder.WithOrigins("https://*.example.com")
               .AllowAnyHeader();
    });

AllowAnyHeader ön kontrol isteklerini ve erişim-denetim-istek-üst bilgi üst bilgisini etkiler. Daha fazla bilgi için bkz. ön kontrol istekleri bölümü.

Tarafından belirtilen belirli başlıklarıyla eşleşen bir CORS ara yazılım ilkesi, WithHeaders yalnızca Access-Control-Request-Headers ' de belirtilen üstbilgiler ile tam olarak eşleşiyorsa mümkündür WithHeaders .

Örneğin, aşağıdaki gibi yapılandırılmış bir uygulamayı göz önünde bulundurun:

app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));

CORS ara yazılımı, Content-Language (headernames. contentlanguage) içinde listelenmediği için aşağıdaki istek üst bilgisi ile bir ön denetim isteğini reddettiğinde WithHeaders :

Access-Control-Request-Headers: Cache-Control, Content-Language

Uygulama 200 ok yanıtı DÖNDÜRÜYOR ancak CORS üst bilgilerini geri göndermez. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez.

Gösterilen yanıt üst bilgilerini ayarlama

Varsayılan olarak tarayıcı, tüm yanıt üst bilgilerini uygulamaya sunmaz. Daha fazla bilgi için bkz. W3C çıkış noktaları arası kaynak paylaşımı (terminoloji): basit yanıt üst bilgisi.

Varsayılan olarak kullanılabilen yanıt üstbilgileri şunlardır:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

CORS belirtimi, bu üst bilgiler basit yanıt üst bilgilerini çağırır. Diğer üst bilgileri uygulama için kullanılabilir hale getirmek için şunu çağırın WithExposedHeaders :

options.AddPolicy("MyExposeResponseHeadersPolicy",
    builder =>
    {
        builder.WithOrigins("https://*.example.com")
               .WithExposedHeaders("x-custom-header");
    });

Kaynaklar arası isteklerde kimlik bilgileri

Kimlik bilgileri CORS isteğinde özel işleme gerektirir. Varsayılan olarak tarayıcı, kimlik bilgilerini bir çapraz kaynak isteğiyle göndermez. Kimlik bilgileri cookie , s ve http kimlik doğrulama düzenlerini içerir. Bir çapraz kaynak isteğiyle kimlik bilgilerini göndermek için, istemcisinin olarak ayarlanması gerekir XMLHttpRequest.withCredentials true .

XMLHttpRequestDoğrudan kullanarak:

var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;

JQuery kullanarak:

$.ajax({
  type: 'get',
  url: 'https://www.example.com/api/test',
  xhrFields: {
    withCredentials: true
  }
});

Fetch API'sini kullanma:

fetch('https://www.example.com/api/test', {
    credentials: 'include'
});

Sunucu kimlik bilgilerine izin vermelidir. Çıkış noktaları arası kimlik bilgilerine izin vermek için şunu arayın AllowCredentials :

options.AddPolicy("MyMyAllowCredentialsPolicy",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .AllowCredentials();
    });

HTTP yanıtı, Access-Control-Allow-Credentials tarayıcıya sunucunun bir çapraz kaynak isteği için kimlik bilgileri verdiğini bildiren bir üst bilgi içerir.

Tarayıcı kimlik bilgilerini gönderirse ancak yanıt geçerli bir Access-Control-Allow-Credentials üst bilgi içermiyorsa, tarayıcı uygulamaya yanıtı kullanıma sunmaz ve çapraz kaynak isteği başarısız olur.

Çıkış noktaları arası kimlik bilgilerine izin vermek bir güvenlik riskidir. Başka bir etki alanındaki Web sitesi, kullanıcının bilgisi olmadan kullanıcı adına, oturum açmış bir kullanıcının kimlik bilgilerini uygulamaya gönderebilir.

CORS belirtimi Ayrıca "*" üst bilgi varsa, çıkış (tüm kaynaklar) ayarının geçersiz olduğunu belirtir Access-Control-Allow-Credentials .

Ön kontrol istekleri

Bazı CORS istekleri için, tarayıcı gerçek isteği yapmadan önce ek bir seçenek isteği gönderir. Bu isteğe bir ön kontrol isteğidenir. Aşağıdaki koşulların Tümü doğruysa tarayıcı, ön kontrol isteğini atlayabilir:

  • İstek yöntemi al, HEAD veya POST.
  • Uygulama,,, veya dışındaki istek üst bilgilerini ayarlanmamış Accept Accept-Language Content-Language Content-Type Last-Event-ID .
  • , Content-Type Ayarlandıysa, aşağıdaki değerlerden birine sahip olan üst bilgi:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

İstemci isteği için ayarlanan istek üst bilgileri kuralı, uygulamanın, nesne üzerinde çağırarak ayarladığı üst bilgiler için geçerlidir setRequestHeader XMLHttpRequest . CORS belirtimi, bu üst bilgiler Yazar istek üst bilgileriniçağırır. Kural,, veya gibi tarayıcının ayarlayabilmesi için, veya gibi bir üst bilgiye uygulanmaz User-Agent Host Content-Length .

Aşağıda, bu belgenin Test CORS bölümündeki [testi koy] düğmesinden yapılmış olan ön kontrol isteğine benzer bir yanıt verilmiştir.

General:
Request URL: https://cors3.azurewebsites.net/api/values/5
Request Method: OPTIONS
Status Code: 204 No Content

Response Headers:
Access-Control-Allow-Methods: PUT,DELETE,GET
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f8...8;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Vary: Origin

Request Headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Method: PUT
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0

Ön kontrol isteği http seçenekleri yöntemini kullanır. Aşağıdaki üstbilgiler bulunabilir:

Ön kontrol isteği reddedilirse, uygulama bir 200 OK yanıt döndürür ancak CORS üst bilgilerini yapmaz. Bu nedenle tarayıcı, çıkış noktaları arası isteği denemez. Reddedilen bir ön kontrol isteğine bir örnek için, bu belgenin Test CORS bölümüne bakın.

Konsol uygulaması, F12 araçlarını kullanarak tarayıcıya bağlı olarak aşağıdakilerden birine benzer bir hata gösterir:

  • Firefox: çapraz kaynak Isteği engellendi: aynı kaynak Ilkesi, konumundaki uzak kaynağı okumaktan izin vermez https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 . (Neden: CORS isteği başarılı olmadı). Daha Fazla Bilgi
  • Chromium tabanlı: ' ' kaynağından ' ' konumundaki getirme erişimi https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 https://cors3.azurewebsites.net CORS ilkesi tarafından engellendi: ön kontrol isteğine verilen yanıt erişim denetimi denetimine geçti: istenen kaynakta ' erişim-control-Allow-origin ' üst bilgisi yok. Donuk bir yanıt ihtiyaçlarınıza hizmet veriyorsa, isteği CORS devre dışı olarak getirmek için isteğin modunu ' No-CORS ' olarak ayarlayın.

Belirli üstbilgilere izin vermek için şunu arayın WithHeaders :

options.AddPolicy("MyAllowHeadersPolicy",
    builder =>
    {
        // requires using Microsoft.Net.Http.Headers;
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

Tüm Yazar isteği başlıklarınaizin vermek için şunu çağırın AllowAnyHeader :

options.AddPolicy("MyAllowAllHeadersPolicy",
    builder =>
    {
        builder.WithOrigins("https://*.example.com")
               .AllowAnyHeader();
    });

Tarayıcılar, nasıl ayarlandıklarından tutarlı değildir Access-Control-Request-Headers . Aşağıdakilerden biri:

  • Üst bilgiler, dışında bir şeye ayarlanır "*"
  • AllowAnyHeader çağrıldı: en az Accept , Content-Type , ve, ve Origin desteklemek istediğiniz tüm özel üstbilgileri ekleyin.

Otomatik ön kontrol istek kodu

CORS ilkesi uygulandığında:

  • ' İ çağırarak küresel olarak app.UseCors Startup.Configure .
  • Özniteliği kullanılıyor [EnableCors] .

ASP.NET Core, ön kontrol seçenekleri isteğine yanıt verir.

Şu anda bir uç nokta temelinde CORS etkinleştirildiğinde RequireCors Otomatik ön kontrol istekleri desteklenmez.

Bu belgenin Test CORS bölümü bu davranışı gösterir.

[HttpOptions] ön kontrol istekleri için öznitelik

cors uygun ilkeyle etkinleştirildiğinde, ASP.NET Core genellikle cors ön denetim isteklerini otomatik olarak yanıtlar. Bazı senaryolarda bu durum olmayabilir. Örneğin, uç nokta yönlendirme Ile CORS'yi kullanma.

Aşağıdaki kod, Seçenekler istekleri için uç noktalar oluşturmak için [HttpOptions] özniteliğini kullanır:

[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
    // OPTIONS: api/TodoItems2/5
    [HttpOptions("{id}")]
    public IActionResult PreflightRoute(int id)
    {
        return NoContent();
    }

    // OPTIONS: api/TodoItems2 
    [HttpOptions]
    public IActionResult PreflightRoute()
    {
        return NoContent();
    }

    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return BadRequest();
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

Önceki kodun test edilmesine ilişkin yönergeler için bkz. Endpoint Routing Ile test CORS ve [HttpOptions] .

Ön kontrol sona erme süresini ayarlama

üst Access-Control-Max-Age bilgisi, kontrol öncesi isteğine yanıtın ne kadar süreyle önbelleğe alın olacağını belirtir. Bu üst bilgileri ayarlamak için çağrısında SetPreflightMaxAge arayın:

options.AddPolicy("MySetPreflightExpirationPolicy",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
    });

CORS nasıl çalışır?

Bu bölümde, BIR CORS isteğinde HTTP iletileri düzeyinde ne olduğu açık edilmektedir.

  • CORS bir güvenlik özelliği değildir. CORS, bir sunucunun aynı çıkış noktası ilkesine gevşettiren bir W3C standardıdır.
    • Örneğin, kötü niyetli bir aktör siteniz üzerinde Çapraz Site Betiği (XSS) kullanabilir ve bilgileri çalması için CORS etkin sitesine bir siteler arası istek yürütebilirsiniz.
  • CORS'ye izin vererek API daha güvenli bir hale gelir.
    • CORS'nin uygulanması istemciye (tarayıcı) göredir. Sunucu isteği yürütür ve yanıtı döndürür; hata döndüren ve yanıtı engelleyen istemcidir. Örneğin, aşağıdaki araçlardan herhangi biri sunucu yanıtını görüntüler:
  • Bu, tarayıcıların çıkış noktası arası XHR veya Fetch API isteği yürütmesine izin vermek için bir sunucudur ve aksi takdirde yasaktır.
    • CORS olmayan tarayıcılar çıkış noktası arası istekte kullanılamaz. CORS'den önce JSONP bu kısıtlamayı yok etmek için kullanıldı. JSONP XHR kullanmaz, yanıtı <script> almak için etiketini kullanır. Betiklerin çıkış noktası arasında yüklenmesine izin verilir.

CORS belirtimi, çıkış noktası arası istekleri etkinleştiren birkaç yeni HTTP üst bilgisi ortaya çıktı. Bir tarayıcı CORS'u destekliyorsa çıkış noktası arası istekler için bu üst bilgileri otomatik olarak ayarlar. CORS'yi etkinleştirmek için özel JavaScript kodu gerekli değildir.

Dağıtılan örnekte PUT test düğmesi

Aşağıda Değerler test düğmesinden 'ye çıkış noktası arası bir istek örneği ve ardından ve ve ve 2. https://cors1.azurewebsites.net/api/values Üst Origin bilgi:

  • İsteği yapan sitenin etki alanını sağlar.
  • Gereklidir ve konaktan farklı olması gerekir.

Genel üst bilgiler

Request URL: https://cors1.azurewebsites.net/api/values
Request Method: GET
Status Code: 200 OK

Yanıt üst bilgileri

Content-Encoding: gzip
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Powered-By: ASP.NET

İstek üst bilgileri

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: cors1.azurewebsites.net
Origin: https://cors3.azurewebsites.net
Referer: https://cors3.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 ...

OPTIONSİsteklerde, sunucu yanıtta Yanıt üst bilgileri üst Access-Control-Allow-Origin: {allowed origin} bilgilerini ayarlar. Örneğin, dağıtılan örneği , Delete [EnableCors] OPTIONS düğme isteği aşağıdaki üst bilgileri içerir:

Genel üst bilgiler

Request URL: https://cors3.azurewebsites.net/api/TodoItems2/MyDelete2/5
Request Method: OPTIONS
Status Code: 204 No Content

Yanıt üst bilgileri

Access-Control-Allow-Headers: Content-Type,x-custom-header
Access-Control-Allow-Methods: PUT,DELETE,GET,OPTIONS
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors3.azurewebsites.net
Vary: Origin
X-Powered-By: ASP.NET

İstek üst bilgileri

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: DELETE
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/test?number=2
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0

Yukarıdaki Yanıt üst bilgisinde, sunucu yanıtta Access-Control-Allow-Origin üst bilgilerini ayarlar. Bu https://cors1.azurewebsites.net üst bilginin değeri, istekten Origin gelen üst bilgiyle eştir.

AllowAnyOriginçağrılırsa Access-Control-Allow-Origin: * joker karakter değeri döndürülür. AllowAnyOrigin herhangi bir çıkış noktası sağlar.

Yanıtta üst bilgi yoksa Access-Control-Allow-Origin çıkış noktası arası istek başarısız olur. Tarayıcı özellikle isteği reddetti. Sunucu başarılı bir yanıt döndürse bile tarayıcı yanıtı istemci uygulamasına kullanılabilir hale getirmz.

SEÇENEKLER isteklerini görüntüleme

Varsayılan olarak Chrome ve Edge tarayıcıları F12 araçlarının ağ sekmesinde OPTIONS isteklerini göstermez. OPTIONS isteklerini bu tarayıcılarda görüntülemek için:

  • chrome://flags/#out-of-blink-cors veya edge://flags/#out-of-blink-cors
  • bayrağını devre dışı bırak.
  • Yeni -den başlatın.

Firefox varsayılan olarak OPTIONS isteklerini gösterir.

IIS'de CORS

IIS'ye dağıtırken, sunucu anonim erişime izin verecek Windows kimlik doğrulaması olmadan önce CORS'nin çalışması gerekir. Bu senaryoyu desteklemek için IIS CORS modülünün uygulama için yüklenmiş ve yapılandırılmış olması gerekir.

CORS'u test etmek

Örnek indirmede CORS'u test etmek için kod vardır. Bkz. indirme. Örnek, Sayfaların ekli olduğu bir API Razor projesidir:

public class StartupTest2
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                        "http://www.contoso.com",
                        "https://cors1.azurewebsites.net",
                        "https://cors3.azurewebsites.net",
                        "https://localhost:44398",
                        "https://localhost:5001")
                            .WithMethods("PUT", "DELETE", "GET");
                });
        });

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

    public void Configure(IApplicationBuilder app)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapRazorPages();
        });
    }
}

Uyarı

WithOrigins("https://localhost:<port>");yalnızca indirme örnek koduna benzer bir örnek uygulamayı test etmek için kullanılmalıdır.

Aşağıdakiler ValuesController test için uç noktaları sağlar:

[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public IActionResult Get() =>
        ControllerContext.MyDisplayRouteInfo();

    // GET api/values/5
    [HttpGet("{id}")]
    public IActionResult Get(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // PUT api/values/5
    [HttpPut("{id}")]
    public IActionResult Put(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);


    // GET: api/values/GetValues2
    [DisableCors]
    [HttpGet("{action}")]
    public IActionResult GetValues2() =>
        ControllerContext.MyDisplayRouteInfo();

}

MyDisplayRouteInfo, Rick.Docs.Samples.RouteInfo NuGet paketi tarafından sağlanır ve yol bilgilerini görüntüler.

Aşağıdaki yaklaşımlardan birini kullanarak önceki örnek kodu test edersiniz:

  • dağıtılan örnek uygulamayı üzerinden https://cors3.azurewebsites.net/ kullanın. Örneği indirmeniz gerek yoktur.
  • Varsayılan dotnet run URL'sini kullanarak örneği ile https://localhost:5001 çalıştırın.
  • url'si için bağlantı Visual Studio 44398 olarak ayarlanmış şekilde Visual Studio'den örneği https://localhost:44398 çalıştırın.

F12 araçlarıyla bir tarayıcı kullanma:

  • Değerler düğmesini seçin ve Ağ sekmesindeki üst bilgileri gözden geçirebilirsiniz.

  • PUT test düğmesini seçin. OPTIONS isteğini görüntüleme yönergeleri için bkz. SEÇENEKLER isteklerini görüntüleme. PUT testi iki istek oluşturur: OPTIONS ön kontrol isteği ve PUT isteği.

  • Başarısız bir GetValues2 [DisableCors] CORS isteğini tetiklemek için düğmeyi seçin. Belgede belirtildiği gibi yanıt 200 başarı döndürür, ancak CORS isteğinde yerlanmaz. CORS hatasını görmek için Konsol sekmesini seçin. Tarayıcıya bağlı olarak aşağıdakine benzer bir hata görüntülenir:

    Çıkış noktası üzerinden getirme erişimi CORS ilkesi tarafından engellendi: İstenen kaynakta 'https://cors1.azurewebsites.net/api/values/GetValues2' 'https://cors3.azurewebsites.net' 'Access-Control-Allow-Origin' üst bilgisi yok. İhtiyaçlarınızı karşılarsa, CORS devre dışı bırakılmış kaynağı getirmek için isteğin modunu 'no-cors' olarak ayarlayın.

CORS özellikli uç noktalar curl , Fiddler veyaPostman gibi bir araçla test edilebilir. Bir araç kullanırken üst bilgi tarafından belirtilen isteğin kaynağı, isteği alan Origin konaktan farklı olması gerekir. İstek, üst bilginin değerine göre çıkış noktası arası Origin değilse:

  • CORS Ara Yazılımı'nın isteği işlemesi gerek yoktur.
  • YANıTta CORS üst bilgileri döndürülz.

Aşağıdaki komut, bir curl OPTIONS isteğinde bilgi almak için kullanır:

curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i

Uç nokta yönlendirme ve [HttpOptions] ile CORS'i test edin

kullanarak CORS'nin uç nokta başına temelinde RequireCors etkinleştirilmesi şu anda otomatik kontrol öncesi isteklerini desteklememektedir. CORS'yi etkinleştirmek için uç nokta yönlendirmeyi kullanan aşağıdaki kodu göz önünde bulundurabilirsiniz:

public class StartupEndPointBugTest
{
    readonly string MyPolicy = "_myPolicy";

    // .WithHeaders(HeaderNames.ContentType, "x-custom-header")
    // forces browsers to require a preflight request with GET

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: MyPolicy,
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com",
                                        "https://cors1.azurewebsites.net",
                                        "https://cors3.azurewebsites.net",
                                        "https://localhost:44398",
                                        "https://localhost:5001")
                           .WithHeaders(HeaderNames.ContentType, "x-custom-header")
                           .WithMethods("PUT", "DELETE", "GET", "OPTIONS");
                });
        });

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

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers().RequireCors(MyPolicy);
            endpoints.MapRazorPages();
        });
    }
}

Aşağıdakiler TodoItems1Controller test için uç noktaları sağlar:

[Route("api/[controller]")]
[ApiController]
public class TodoItems1Controller : ControllerBase
{
    // PUT: api/TodoItems1/5
    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return Content($"ID = {id}");
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // Delete: api/TodoItems1/5
    [HttpDelete("{id}")]
    public IActionResult MyDelete(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // GET: api/TodoItems1
    [HttpGet]
    public IActionResult GetTodoItems() =>
        ControllerContext.MyDisplayRouteInfo();

    [EnableCors]
    [HttpGet("{action}")]
    public IActionResult GetTodoItems2() =>
        ControllerContext.MyDisplayRouteInfo();

    // Delete: api/TodoItems1/MyDelete2/5
    [EnableCors]
    [HttpDelete("{action}/{id}")]
    public IActionResult MyDelete2(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);
}

Dağıtılan örneğin test sayfasından yukarıdaki kodu test edin.

Uç noktaların kontrol öncesi isteklerine sahip olması ve yanıt vermesi nedeniyle Sil [EnableCors] ve GET [EnableCors] [EnableCors] düğmeleri başarılı olur. Diğer uç noktalar başarısız olur. JavaScript şunları gönderdiği için GET düğmesi başarısız olur:

 headers: {
      "Content-Type": "x-custom-header"
 },

Aşağıdakiler TodoItems2Controller benzer uç noktalar sağlar, ancak OPTIONS isteklerine yanıt vermek için açık kod içerir:

[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
    // OPTIONS: api/TodoItems2/5
    [HttpOptions("{id}")]
    public IActionResult PreflightRoute(int id)
    {
        return NoContent();
    }

    // OPTIONS: api/TodoItems2 
    [HttpOptions]
    public IActionResult PreflightRoute()
    {
        return NoContent();
    }

    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return BadRequest();
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // [EnableCors] // Not needed as OPTIONS path provided
    [HttpDelete("{id}")]
    public IActionResult MyDelete(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    [EnableCors]  // Rquired for this path
    [HttpGet]
    public IActionResult GetTodoItems() =>
        ControllerContext.MyDisplayRouteInfo();

    [HttpGet("{action}")]
    public IActionResult GetTodoItems2() =>
        ControllerContext.MyDisplayRouteInfo();

    [EnableCors]  // Rquired for this path
    [HttpDelete("{action}/{id}")]
    public IActionResult MyDelete2(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);
}

Dağıtılan örneğin test sayfasından önceki kodu test edin. Denetleyici açılan listesinde Preflight'ı ve ardından Set Controller 'ı seçin. Uç noktalara yapılan tüm CORS TodoItems2Controller çağrıları başarılı olur.

Ek kaynaklar