Cara mengaktifkan CORS di ASP.net Core WebAPI

190

Apa yang saya coba lakukan

Saya memiliki API Web Inti ASP.Net backend yang dihosting pada Paket Gratis Azure (Kode Sumber: https://github.com/killerrin/Portfolio-Backend ).

Saya juga memiliki Situs Web Klien yang ingin saya konsumsi menggunakan API itu. Aplikasi Klien tidak akan di-host di Azure, tetapi akan di-host di Halaman Github atau di Layanan Web Hosting lain yang saya punya akses. Karena itu, nama domain tidak akan berbaris.

Melihat ke dalam ini, saya perlu mengaktifkan CORS di sisi API Web, namun saya telah mencoba hampir semuanya selama beberapa jam sekarang dan menolak untuk bekerja.

Bagaimana Saya Mengeset Klien Hanya klien sederhana yang ditulis dalam React.js. Saya menelepon API melalui AJAX di Jquery. Situs Bereaksi berfungsi jadi saya tahu bukan itu. Panggilan Jquery API berfungsi seperti yang saya konfirmasikan dalam Percobaan 1. Berikut adalah cara saya melakukan panggilan

    var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
    //alert(username + "|" + password + "|" + apiUrl);
    $.ajax({
        url: apiUrl,
        type: "POST",
        data: {
            username: username,
            password: password
        },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            var authenticatedUser = JSON.parse(response);
            //alert("Data Loaded: " + authenticatedUser);
            if (onComplete != null) {
                onComplete(authenticatedUser);
            }
        },
        error: function (xhr, status, error) {
            //alert(xhr.responseText);
            if (onComplete != null) {
                onComplete(xhr.responseText);
            }
        }
    });

Apa yang saya coba


Percobaan 1 - Cara yang 'pantas'

https://docs.microsoft.com/en-us/aspnet/core/security/cors

Saya telah mengikuti tutorial ini di Situs Web Microsoft ke T, mencoba semua 3 opsi untuk mengaktifkannya secara global di Startup.cs, Menyiapkannya di setiap pengontrol dan Mencoba di setiap Tindakan.

Mengikuti metode ini, Cross Domain berfungsi, tetapi hanya pada Aksi tunggal pada pengontrol tunggal (POST ke AccountController). Untuk yang lainnya, Microsoft.AspNetCore.Corsmiddleware menolak untuk mengatur header.

Saya menginstal Microsoft.AspNetCore.Corsmelalui NUGET dan versinya1.1.2

Ini adalah bagaimana saya mengaturnya di Startup.cs

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Cors
        services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));

        // Add framework services.
        services.AddMvc();
        services.Configure<MvcOptions>(options =>
        {
            options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
        });

        ...
        ...
        ...
    }

    // This method gets called by the runtime. Use this method to configure 
    //the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        // Enable Cors
        app.UseCors("MyPolicy");

        //app.UseMvcWithDefaultRoute();
        app.UseMvc();

        ...
        ...
        ...
    }

Seperti yang Anda lihat, saya melakukan semua yang diperintahkan. Saya menambahkan Cors sebelum MVC dua kali, dan ketika itu tidak berhasil saya mencoba memakai [EnableCors("MyPolicy")]setiap pengontrol seperti itu

[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller

Mencoba 2 - Brute Memaksakannya

https://andrewlock.net/adding-default-security-headers-in-asp-net-core/

Setelah beberapa jam mencoba pada upaya sebelumnya, saya pikir saya akan mencoba bruteforce dengan mencoba mengatur header secara manual, memaksa mereka untuk berjalan di setiap respons. Saya melakukan ini mengikuti tutorial ini tentang cara menambahkan header secara manual ke setiap respons.

Ini adalah tajuk yang saya tambahkan

.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")

Ini adalah tajuk lain yang saya coba yang gagal

.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")

Dengan metode ini, header Cross Site sedang diterapkan dengan benar dan mereka muncul di konsol pengembang saya dan di Postman. Namun masalahnya adalah bahwa sementara melewati Access-Control-Allow-Origincek, webbrowser melempar fit (saya percaya) Access-Control-Allow-Headersmenyatakan415 (Unsupported Media Type)

Jadi metode brute force juga tidak berfungsi


Akhirnya

Adakah yang berhasil melakukan ini dan bisa membantu, atau hanya bisa mengarahkan saya ke arah yang benar?


EDIT

Jadi untuk mendapatkan panggilan API, saya harus berhenti menggunakan JQuery dan beralih ke XMLHttpRequestformat Javascript Murni .

Percobaan 1

Saya berhasil mendapatkan Microsoft.AspNetCore.Corsuntuk bekerja dengan mengikuti jawaban MindingData, kecuali dalam ConfigureMetode menempatkan app.UseCorssebelumnya app.UseMvc.

Selain itu, ketika dicampur dengan Javascript API Solution options.AllowAnyOrigin()untuk dukungan wildcard mulai berfungsi juga.

Percobaan 2

Jadi saya telah berhasil mendapatkan Percobaan 2 (brute forcing it) untuk bekerja ... dengan satu-satunya pengecualian bahwa Wildcard untuk Access-Control-Allow-Origintidak berfungsi dan karena itu saya harus secara manual mengatur domain yang memiliki akses ke sana.

Ini jelas tidak ideal karena saya hanya ingin WebAPI ini dibuka lebar untuk semua orang, tetapi setidaknya ini berfungsi untuk saya di situs terpisah, yang berarti ini adalah permulaan

app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
    .AddDefaultSecurePolicy()
    .AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
    .AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
    .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));
pembunuh
sumber
2
Untuk 415 (Unsupported Media Type)masalah Anda , atur Content-Typetajuk permintaan ke application/json.
Technetium
5
Terima kasih telah meluangkan waktu untuk menulis pertanyaan deskriptif.
user1007074
1
Jika Anda menguji menggunakan Tukang Pos, pastikan Anda mengatur Asal ke * atau sesuatu untuk tajuk permintaan, maka Percobaan # 1 seharusnya berfungsi. Tanpa tajuk ini, Access-Control-Allow-Origin tidak akan dikembalikan di tajuk respons.
tala9999

Jawaban:

240

Karena Anda memiliki kebijakan CORS yang sangat sederhana (Izinkan semua permintaan dari domain XXX), Anda tidak perlu membuatnya terlalu rumit. Coba lakukan hal berikut terlebih dahulu (Implementasi CORS yang sangat mendasar).

Jika Anda belum melakukannya, instal paket nuget CORS.

Install-Package Microsoft.AspNetCore.Cors

Dalam metode ConfigureServices di startup.cs Anda, tambahkan layanan CORS.

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(); // Make sure you call this previous to AddMvc
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Kemudian dalam metode Konfigurasikan startup.cs Anda, tambahkan berikut ini:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Make sure you call this before calling app.UseMvc()
    app.UseCors(
        options => options.WithOrigins("http://example.com").AllowAnyMethod()
    );

    app.UseMvc();
}

Sekarang cobalah. Kebijakan adalah ketika Anda menginginkan kebijakan yang berbeda untuk tindakan yang berbeda (mis. Host yang berbeda atau header berbeda). Untuk contoh sederhana Anda, Anda benar-benar tidak membutuhkannya. Mulailah dengan contoh sederhana ini dan atur sesuai kebutuhan dari sana.

Bacaan lebih lanjut: http://dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/

MindingData
sumber
3
XMLHttpRequest tidak dapat memuat andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication . Respons terhadap permintaan preflight tidak lulus pemeriksaan kontrol akses: Tidak ada tajuk 'Akses-Kontrol-Bolehkan-Asal' hadir pada sumber daya yang diminta. Karena itu, ' localhost: 3000 ' tidak diizinkan mengakses. Responsnya memiliki kode status HTTP 415.
killerrin
7
Ini tidak akan berhasil, ketika Anda mendaftar app.UseCors SETELAH `` app.UseMvc () `. Middlewares dieksekusi sesuai urutannya
Tseng
24
menggunakan app.UseCors sebelum app.UseMvc, dalam metode Configure tampaknya berfungsi. Untuk beberapa alasan, urutannya sepertinya penting.
MrClan
1
Bagi saya, masalah terbesar dari CORS di 2.0 adalah bahwa ia tidak tahu apa yang salah, hanya diam-diam gagal mengatur header CORS. Catatan : ingatlah untuk menambahkan semua tajuk wajib Anda ke kebijakan atau itu akan gagal (saya punya tipe konten). Juga hal yang aneh bagi saya bahwa middleware CORS tidak mengerem pemrosesan permintaan, hanya menginformasikan dalam log bahwa asal tidak diizinkan dan .. Melewati permintaan lebih lanjut (pesanan middleware sudah benar).
Andrii M4n0w4R
2
Saya harus mengaktifkan options.DisableHttpsRequirement();agar semua ini berfungsi. Sepertinya pengaturan https cors tidak berlaku.
Michael Brown
210
  • Dalam ConfigureServices tambahkan services.AddCors(); SEBELUM layanan.AddMvc ();

  • Tambahkan UseCors di Configure

     app.UseCors(builder => builder
         .AllowAnyOrigin()
         .AllowAnyMethod()
         .AllowAnyHeader());   
     app.UseMvc();
    

Poin utama adalah add itu app.UseCorssebelumnya app.UseMvc().

Pastikan Anda mendeklarasikan fungsionalitas CORS sebelum MVC sehingga middleware menyala sebelum pipa MVC mengontrol dan mengakhiri permintaan.

Setelah metode di atas berfungsi, Anda dapat mengubahnya mengonfigurasi ASAL tertentu untuk menerima panggilan api dan menghindari membiarkan API Anda terbuka bagi siapa pun

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
    {
        builder.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
    }));

    services.AddMvc();
}

Dalam metode configure, beri tahu CORS untuk menggunakan kebijakan yang baru saja Anda buat:

app.UseCors("ApiCorsPolicy");
app.UseMvc();

Saya baru saja menemukan artikel ringkas ini tentang subjek - https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi

Ji Ra
sumber
1
Ini bekerja untuk saya. codeproject.com/Articles/1150023/...
hubert17
17
Ini harus benar-benar mendapatkan lebih banyak upvotes sebagai titik awal yang bagus. Dalam pengalaman saya selama lebih dari 25 tahun pengkodean, selalu menyenangkan mengetahui cara membuka pintu air untuk memastikannya benar-benar "berfungsi" dan kemudian menutup / mengamankan hal-hal yang diperlukan.
Indy-Jones
4
Hanya untuk menyebutkan ini, berbeda dengan Configure()pesanan tidak terlalu penting di sini dalamConfigureServices()
B12Toaster
Saya menggunakan tautan dalam Pustaka Selanjutnya dan langkah-langkah tersebut mengatasi kesalahan ini. Saya tidak yakin di mana perubahan ini harus ditempatkan (saya pikir API). Tautan tersebut mengkonfirmasi bahwa mereka harus ditempatkan di API. Terima kasih untuk bantuannya. Saya benar-benar memutar roda saya dengan kesalahan ini.
Richard
1
FYI - Spesifikasi CORS juga menyatakan bahwa pengaturan asal ke "*" (semua asal) tidak valid jika tajuk Akses-Kontrol-Bolehkan-Kredensial hadir. Berarti Anda tidak dapat menggunakan AllowCredentials()dengan AllowAnyOrigin()seperti di atas. Untuk menggunakan, AllowCredentials()Anda perlu mengatur WithOrigins(). docs.microsoft.com/en-us/aspnet/core/security/…
Nick De Beer
28

Saya membuat kelas middleware saya sendiri yang bekerja untuk saya, saya pikir ada sesuatu yang salah dengan .net core middleware class

public class CorsMiddleware
{
    private readonly RequestDelegate _next;

    public CorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
        httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
        return _next(httpContext);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
    public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CorsMiddleware>();
    }
}

dan menggunakannya dengan cara ini di startup.cs

app.UseCorsMiddleware();
pengguna8266077
sumber
Cara yang sangat elegan untuk menjalankan Access-Control-Allow-Origin.
Artur Poniedziałek
Ini berfungsi di WebAPI dan MVC dan tidak memiliki dependensi, Terima kasih!
Joe
Saya skeptis tentang ini juga, tetapi itu berhasil untuk saya. Saya mencoba pada dasarnya setiap metode lain untuk mencapai hal ini yang dapat saya temukan di internet, tetapi tidak peduli apa server tidak akan menanggapi dengan header akses. Ini bekerja dengan baik. Saya menjalankan aspnetcore 2.1.
Jordan
Anda harus mengembalikan tajuk kor hanya jika klien mengirim tajuk "Asal" dalam permintaan. Dalam CospMiddleware asli terlihat seperti ini:if (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) return this._next(context);
Andrew Prigorshnev
2
Mungkin "ada yang salah dengan .net core middleware class" karena Anda tidak menambahkan header "Origin" saat mengujinya dengan ikal atau sesuatu seperti ini. Browser menambahkan header ini secara otomatis ketika Anda membuat permintaan dalam kode js.
Andrew Prigorshnev
18

Dalam kasus saya, getpermintaan hanya berfungsi dengan baik sesuai dengan jawaban MindingData. Untuk jenis permintaan lain, Anda perlu menulis:

app.UseCors(corsPolicyBuilder =>
   corsPolicyBuilder.WithOrigins("http://localhost:3000")
  .AllowAnyMethod()
  .AllowAnyHeader()
);

Jangan lupa menambahkan .AllowAnyHeader()

Towhid
sumber
Setuju dengan Towhid bahwa AllowAnyHeader () diperlukan. Itu memungkinkan server menerima permintaan PILIHAN jika permintaan HEADER melewatkan sesuatu.
Rivon
The. AllowAnyHeader () melakukannya untuk saya, saya mengalami masalah dengan respons preflight.
takaz
11

Untuk memperluas user8266077 's jawaban , saya menemukan bahwa saya masih perlu respon PILIHAN pasokan untuk permintaan preflight di NET Inti 2.1-preview untuk kasus penggunaan saya:

// https://stackoverflow.com/a/45844400
public class CorsMiddleware
{
  private readonly RequestDelegate _next;

  public CorsMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
    context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    // Added "Accept-Encoding" to this list
    context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Accept-Encoding, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
    context.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
    // New Code Starts here
    if (context.Request.Method == "OPTIONS")
    {
      context.Response.StatusCode = (int)HttpStatusCode.OK;
      await context.Response.WriteAsync(string.Empty);
    }
    // New Code Ends here

    await _next(context);
  }
}

dan kemudian mengaktifkan middleware seperti di Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseMiddleware(typeof(CorsMiddleware));
  // ... other middleware inclusion such as ErrorHandling, Caching, etc
  app.UseMvc();
}
ckr
sumber
1
Saya sarankan menambahkan middleware seperti itu:app.Use<CorsMiddleware>();
Albert221
Anda dapat mengganti 2 ligne itu: context.Response.StatusCode = (int) HttpStatusCode.OK; menunggu konteks.Response.WriteAsync (string.Empty); dengan sederhana: kembali;
Hayha
1
Untuk memperluas perluasan jawaban @ user8266077 Anda: Berhati-hatilah bahwa jika permintaan karena alasan lain gagal, middleware ini akan melempar pengecualian dan header tidak akan ditetapkan. Artinya di frontend, masih akan terlihat seperti masalah CORS meskipun itu sesuatu yang sama sekali berbeda. Saya melewati ini dengan menangkap pengecualian await _next(context)dan pengaturan kode status dan respons secara manual jika ini terjadi. Saya juga harus menambahkan "otorisasi" ke Access-Control-Allow-Header agar permintaan preflight berfungsi ketika membuat permintaan dari reaksi yang memerlukan otorisasi.
Adam
11
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {      
       app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()
            );
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
    }
Mo D Genesis
sumber
.SetIsOriginAllowed ((host) => true) menyelesaikannya untuk saya.
JensB
wow, jadi saya sepenuhnya mengharapkan jawaban lain untuk bekerja sebelum si kecil ini dengan hanya 3 suara. tapi saya dengan cermat mencoba masing-masing, ... pada kemauan saya pergi untuk Anda dan, itu berhasil. terima kasih
roberto tomás
Ini adalah yang bekerja untuk saya di. NET Core 3.1 untuk memungkinkan hampir semua hal
JustinHui
10

Saya berjuang dengan ini untuk HARI.

Saya akhirnya berhasil bekerja dengan pindah app.UseCors(CORS_POLICY);ke TOP of Configure().

https://weblog.west-wind.com/posts/2016/sep/26/aspnet-core-and-cors-gotchas

Pastikan Anda mendeklarasikan fungsionalitas CORS sebelum> MVC karena header harus diterapkan sebelum MVC menyelesaikan permintaan.

<= Meskipun aplikasi saya tidak menelepon UseMVC(), pindah UseCors()ke atas memperbaiki masalah

Juga:

  • Microsoft.AspNetCore.Corsdulu paket NuGet yang diperlukan dalam .Net Core 2 dan yang lebih rendah; sekarang secara otomatis menjadi bagian dari Microsoft.AspNetCore di .Net Core 3 dan lebih tinggi.
  • builder.AllowAnyOrigin()dan .AllowCredentials()opsi CORS sekarang saling eksklusif di .Net Core 3 dan yang lebih tinggi
  • Kebijakan CORS tampaknya membutuhkan server Angular call https. URL http tampaknya memberikan kesalahan CORS terlepas dari konfigurasi CORS server Net. Misalnya, http://localhost:52774/api/Contactsakan memberikan kesalahan CORS; cukup mengubah URL menjadi https://localhost:44333/api/Contactsberfungsi.

Catatan tambahan :

Dalam kasus saya, CORS tidak akan berfungsi sampai saya pindah ke app.UseCors()atas app.UseEndpoints(endpoints => endpoints.MapControllers()).

FoggyDay
sumber
2
Yang ini harus menjadi jawabannya jika Anda menggunakan Net Core 3. Terima kasih telah menyelamatkan hidup saya!
Kanada Wan
2
"Dengan perutean titik akhir, middleware CORS harus dikonfigurasikan untuk mengeksekusi di antara panggilan ke UseRouting dan UseEndpoints. Konfigurasi yang salah akan menyebabkan middleware berhenti berfungsi dengan benar." di sini docs.microsoft.com/en-us/aspnet/core/security/…
Mark Schultheiss
"Dengan perutean titik akhir, middleware CORS harus dikonfigurasikan untuk mengeksekusi di antara panggilan ke UseRouting dan UseEndpoints. Konfigurasi yang salah akan menyebabkan middleware berhenti berfungsi dengan benar." di sini docs.microsoft.com/en-us/aspnet/core/security/…
Mark Schultheiss
7

Tak satu pun dari prosedur di atas yang membantu dan saya kemudian membaca artikel yang menyelesaikan masalah.

Di bawah ini adalah kode.

public void ConfigureServices(IServiceCollection services)
{
    // Add service and create Policy with options
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials() );
    });


    services.AddMvc(); 
}

dan

public void Configure(IApplicationBuilder app)
{
    // ...

    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");

dan di atas metode tindakan saya

[EnableCors("CorsPolicy")]
Sainath
sumber
2
Ini mungkin ide yang buruk: Anda tidak boleh mencampur middleware ( app.UseCors()) dengan [EnableCors()]dalam aplikasi yang sama. Anda harus menggunakan satu atau yang lain - tetapi tidak keduanya: docs.microsoft.com/en-us/aspnet/core/security/… :Use the [EnableCors] attribute or middleware, not both in the same app.
FoggyDay
4

coba tambahkan jQuery.support.cors = true;sebelum panggilan Ajax

Bisa juga bahwa data yang Anda kirim ke API tidak jelas,

coba tambahkan fungsi JSON berikut

        var JSON = JSON || {};

    // implement JSON.stringify serialization
    JSON.stringify = JSON.stringify || function (obj) {

        var t = typeof (obj);
        if (t != "object" || obj === null) {

            // simple data type
            if (t == "string") obj = '"' + obj + '"';
            return String(obj);

        }
        else {

            // recurse array or object
            var n, v, json = [], arr = (obj && obj.constructor == Array);

            for (n in obj) {
                v = obj[n]; t = typeof (v);

                if (t == "string") v = '"' + v + '"';
                else if (t == "object" && v !== null) v = JSON.stringify(v);

                json.push((arr ? "" : '"' + n + '":') + String(v));
            }

            return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
        }
    };

    // implement JSON.parse de-serialization
    JSON.parse = JSON.parse || function (str) {
        if (str === "") str = '""';
        eval("var p=" + str + ";");
        return p;
    };

lalu di data Anda: objek ubah ke

    data: JSON.stringify({
        username: username,
        password: password
    }),
Riaan Saayman
sumber
Terima kasih atas bantuan Anda. Pasti memanfaatkan sebagian dari jawaban untuk mencari solusi pada akhirnya setelah menggabungkan jawaban everyones
killerrin
4

Solusi paling sederhana adalah tambahkan

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

        app.UseCors(options => options.AllowAnyOrigin());

        app.UseHttpsRedirection();
        app.UseMvc();
    }

ke Startup.cs.

amilamad
sumber
3

Saya pikir jika Anda menggunakan Anda sendiri CORS middleware Anda perlu memastikan itu benar-benar Cors permintaan dengan memeriksa asal sundulan.

 public class CorsMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMemoryCache _cache;
    private readonly ILogger<CorsMiddleware> _logger;

    public CorsMiddleware(RequestDelegate next, IMemoryCache cache, ILogger<CorsMiddleware> logger)
    {
        _next = next;
        _cache = cache;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context, IAdministrationApi adminApi)
    {
        if (context.Request.Headers.ContainsKey(CorsConstants.Origin) || context.Request.Headers.ContainsKey("origin"))
        {
            if (!context.Request.Headers.TryGetValue(CorsConstants.Origin, out var origin))
            {
                context.Request.Headers.TryGetValue("origin", out origin);
            }

            bool isAllowed;
            // Getting origin from DB to check with one from request and save it in cache 
            var result = _cache.GetOrCreateAsync(origin, async cacheEntry => await adminApi.DoesExistAsync(origin));
            isAllowed = result.Result.Result;

            if (isAllowed)
            {
                context.Response.Headers.Add(CorsConstants.AccessControlAllowOrigin, origin);
                context.Response.Headers.Add(
                    CorsConstants.AccessControlAllowHeaders,
                    $"{HeaderNames.Authorization}, {HeaderNames.ContentType}, {HeaderNames.AcceptLanguage}, {HeaderNames.Accept}");
                context.Response.Headers.Add(CorsConstants.AccessControlAllowMethods, "POST, GET, PUT, PATCH, DELETE, OPTIONS");

                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("CORS with origin {Origin} was handled successfully", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                await _next(context);
            }
            else
            {
                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("Preflight CORS request with origin {Origin} was declined", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                _logger.LogInformation("Simple CORS request with origin {Origin} was declined", origin);
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                return;
            }
        }

        await _next(context);
    }
Riddik
sumber
Terima kasih banyak. Saya hampir menjadi gila, bertanya pada diri sendiri mengapa Access-Control-Allow-Originheader tidak dikeluarkan oleh server. Sebenarnya saya mengirim permintaan melalui tukang pos tanpa Originheader. Ini menyelamatkan hari saya! (Atau setidaknya pagi hari;))
Paul Kertscher
2

Berdasarkan komentar Anda dalam jawaban MindingData, itu tidak ada hubungannya dengan CORS Anda, itu berfungsi dengan baik.

Tindakan Pengontrol Anda mengembalikan data yang salah. HttpCode 415 berarti, "Jenis media yang tidak didukung". Ini terjadi ketika Anda memberikan format yang salah ke controller (yaitu XML ke controller yang hanya menerima json) atau ketika Anda mengembalikan tipe yang salah (mengembalikan Xml dalam controller yang dinyatakan hanya mengembalikan xml).

Untuk nanti periksa keberadaan [Produces("...")]atribut pada tindakan Anda

Tseng
sumber
Terima kasih atas bantuan Anda. Mencoba solusi baru dan bermain dengan json yang dikirim keluar dan itu berhasil setelah saya menggantinya dan berhasil
killerrin
2

Bagi saya, itu tidak ada hubungannya dengan kode yang saya gunakan. Untuk Azure kami harus masuk ke pengaturan Layanan Aplikasi, pada menu samping entri "CORS". Di sana saya harus menambahkan domain tempat saya meminta barang. Begitu saya memilikinya, semuanya ajaib.

kjbetz
sumber
2

Di launchSettings.json, di bawah iisSettings, atur anonymousAuthentication menjadi true:

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:4200/",
      "sslPort": 0
    }
  }

Kemudian, di Startup.cs, di bawah ConfigureServices, sebelum services.AddMvc, tambahkan:

services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
    builder
        .AllowAnyOrigin()
        .WithHeaders(HeaderNames.AccessControlAllowHeaders, "Content-Type")
        .AllowAnyMethod()
        .AllowCredentials();
}));

dan kemudian, dalam metode configure, sebelum app.UseMvc () tambahkan:

app.UseCors("ApiCorsPolicy");
Adrian
sumber
Ini melakukannya untuk saya, saya awalnya mengatur proyek saya untuk Windows Authentication tetapi kemudian harus mengubahnya menjadi anonim, saya telah mengkonfigurasi CORS dengan benar tetapi pengaturan ini di launchSettings.json adalah biang keladinya, terima kasih telah memposting ini !.
HaRoLD
2

Saya menggunakan .Net CORE 3.1 dan saya menghabiskan waktu lama untuk membenturkan kepala ke dinding dengan yang ini ketika saya menyadari bahwa kode saya sudah mulai bekerja tetapi lingkungan debug saya rusak, jadi inilah 2 petunjuk jika Anda mencoba memecahkan masalah masalah:

  1. Jika Anda mencoba mencatat tajuk respons menggunakan middleware ASP.NET, tajuk "Access-Control-Allow-Origin" tidak akan pernah muncul meskipun ada di sana. Saya tidak tahu bagaimana, tetapi tampaknya ditambahkan di luar pipa (pada akhirnya saya harus menggunakan wireshark untuk melihatnya).

  2. .NET CORE tidak akan mengirim "Akses-Kontrol-Izinkan-Asal" dalam respons kecuali Anda memiliki header "Asal" dalam permintaan Anda. Tukang pos tidak akan menyetel ini secara otomatis sehingga Anda harus menambahkannya sendiri.

Andy
sumber
2

Dalam kasus saya, saya memperbaiki dengan UseCors sebelum UserRouting ..

René Bizelli de Oliveira
sumber
Saya mengalami hal yang serupa ketika saya memutakhirkan dari dotnet core 2.2 ke 3.1. Harus memindahkan app.UseCors () di atas app.UseRouting (). Jawaban ini menunjuk saya ke arah yang benar.
Brandonm
1

.NET Core 3.1

Bekerja untuk saya dan bagaimana dokumen mengatakan untuk melakukannya:

di kelas Startup:

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; 

Dalam metode ConfigureServices ():

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

Dalam metode Konfigurasikan ():

    app.UseCors(MyAllowSpecificOrigins);  

https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1

Andrew
sumber
0

Saya mendapat jawaban MindingData di atas untuk bekerja, tetapi saya harus menggunakan Microsoft.AspNet.Cors, bukan Microsoft.AspNetCore.Cors. Saya menggunakan proyek .NetCore Aplikasi Web API di Visual Studio 2019

carl
sumber
2
CATATAN: Anda tidak boleh menggunakan Microsoft.AspNet.Cors dalam aplikasi ASP.Net Cor. Jika Anda menggunakan .Net Core 3.0 atau lebih tinggi, Anda tidak perlu mengimpor paket NuGet sama sekali untuk CORS. Jika Anda menggunakan .Net Core 2.3 atau lebih rendah, maka Anda memerlukan versi yang sesuai dari Microsoft.AspNet.Cors dari NuGet.
FoggyDay
0

Itu

Microsoft.AspNetCore.Cors

akan memungkinkan Anda untuk melakukan CORS dengan fitur bawaan, tetapi tidak menangani permintaan PILIHAN. Solusi terbaik sejauh ini adalah menciptakan Middleware baru seperti yang disarankan dalam posting sebelumnya. Periksa jawaban yang ditandai benar di pos berikut:

Aktifkan tajuk OPSI untuk CORS di .NET Core Web API

Bonomi
sumber
0

Cara sederhana dan mudah untuk melakukannya.

  1. Instal paket

Install-Package Microsoft.AspNetCore.Cors

  1. Masukkan kode di bawah ini dalam file startup.cs

app.UseCors(options => options.AllowAnyOrigin());

pintu sharma
sumber
0

Ini kode saya:)

  app.Use((ctx, next) =>
        {
            ctx.Response.Headers.Add("Access-Control-Allow-Origin", ctx.Request.Headers["Origin"]);
            ctx.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            ctx.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            ctx.Response.Headers.Add("Access-Control-Allow-Headers", "AccessToken,Content-Type");
            ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
            if (ctx.Request.Method.ToLower() == "options")
            {
                ctx.Response.StatusCode = 204;

                return Task.CompletedTask;
            }
            return next();
        });
Lnn
sumber
0

Inilah cara saya melakukan ini.

Saya melihat bahwa dalam beberapa jawaban mereka mengatur app.UserCors("xxxPloicy")dan memasukkan [EnableCors("xxxPloicy")]pengontrol. Anda tidak perlu melakukan keduanya.

Inilah langkah-langkahnya.

Di Startup.cs di dalam ConfigureServices tambahkan kode berikut.

    services.AddCors(c=>c.AddPolicy("xxxPolicy",builder => {
        builder.AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    }));

Jika Anda ingin menerapkan seluruh proyek maka tambahkan kode berikut dalam metode Konfigurasi di Startup.cs

app.UseCors("xxxPolicy");

Atau

Jika Anda ingin menambahkannya ke pengontrol spesifik maka tambahkan aktifkan kode kor seperti yang ditunjukkan di bawah ini.

[EnableCors("xxxPolicy")]
[Route("api/[controller]")]
[ApiController]
public class TutorialController : ControllerBase {}

Untuk info lebih lanjut: lihat ini

Arshath Shameer
sumber
0

Gunakan atribut Action / Controller kustom untuk mengatur header CORS.

Contoh:

public class AllowMyRequestsAttribute : ControllerAttribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        // check origin
        var origin = context.HttpContext.Request.Headers["origin"].FirstOrDefault();
        if (origin == someValidOrigin)
        {
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", origin);
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            // Add whatever CORS Headers you need.
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // empty
    }
}

Kemudian di Web API Controller / Action:

[ApiController]
[AllowMyRequests]
public class MyController : ApiController
{
    [HttpGet]
    public ActionResult<string> Get()
    {
        return "Hello World";
    }
}
warrickh
sumber
0

Hanya untuk menambahkan untuk menjawab di sini, jika Anda menggunakan app.UseHttpsRedirection(), dan Anda tidak memukul port SSL mempertimbangkan berkomentar ini.

Raj
sumber
0

Saya menggunakan blassor webassembly sebagai client dan asp.net web api core sebagai backend dan memiliki masalah kors juga.

Saya menemukan solusi dengan kode ini:

Inti web api ASP.Net saya Startup.cs ConfigureServices dan Metode konfigurasi baris pertama terlihat seperti ini:

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

 //other code below...
}

dan metode Konfigurasi saya:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseCors(
        options =>   options.WithOrigins("http://example.com").AllowAnyMethod().AllowAnyHeader()
            );
 //other code below...
}

ubah http://example.comdengan domain klien atau alamat ip Anda

Zviadi
sumber
-1
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddJsonOptions(options => {
                    var resolver = options.SerializerSettings.ContractResolver;
                    if (resolver != null)
                        (resolver as DefaultContractResolver).NamingStrategy = null;
                });

            services.AddDbContext<PaymentDetailContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DevConnection"))); //Dependency Injection
            // options => options.UseSqlServer() Lamda Expression

            services.AddCors(options =>
            {
                options.AddPolicy(MyAllowSpecificOrigins,
                    builder =>
                    {
                        builder.WithOrigins("http://localhost:4200").AllowAnyHeader()
                                .AllowAnyMethod(); ;
                    });
            });
Albin CS
sumber
Harap edit jawaban Anda untuk memasukkan dan penjelasan kode Anda dan bagaimana perbedaannya dari jawaban lainnya. Ini akan membuat posting Anda lebih bermanfaat dan lebih besar kemungkinannya untuk di
upgrade