Aspnetcore: HTTP 500 jika permintaan ke titik akhir yang mendukung CORS diminta tanpa header Asal

Dibuat pada 13 Apr 2019  ·  3Komentar  ·  Sumber: dotnet/aspnetcore

Jelaskan bugnya

Jika permintaan HTTP dibuat ke titik akhir berkemampuan CORS di mana header permintaan HTTP origin tidak ditentukan, permintaan gagal dengan kesalahan HTTP 500.

Pengecualian dalam log adalah:

[2019-04-13 14:40:04Z] fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Endpoint MartinCostello.Api.Controllers.TimeController.Get (API) contains CORS metadata, but a middleware was not found that supports CORS.
Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code.
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.ThrowMissingCorsMiddlewareException(Endpoint endpoint)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.HttpOverrides.HttpMethodOverrideMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Namun, app.Cors() _has_ telah ditambahkan ke aplikasi sebelum app.UseEndpoints(...) .

Ini tampaknya telah diperkenalkan oleh #9181.

Jika permintaan tidak memiliki header permintaan origin , maka middleware CORS dilewati:

https://github.com/aspnet/AspNetCore/blob/b93bc433db66175d2b07b128ec9990f7a4dd7e1b/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs#L122 -L125

Namun, middleware titik akhir menemukan metadata CORS pada titik akhir yang dipanggil, dan memeriksa apakah middleware CORS dipanggil (yang memang demikian, tetapi dilewati karena tidak diperlukan) dengan mencari kunci di HttpContext 's item. Item tidak ada, jadi pengecualian dilemparkan:

https://github.com/aspnet/AspNetCore/blob/84da613d2c03b6f1c0fa3c01828923ec3415d525/src/Http/Routing/src/EndpointMiddleware.cs#L51 -L55

Kunci yang diuji oleh middleware titik akhir hanya ditambahkan jika header origin ada dalam permintaan, yang ada di sini:

https://github.com/aspnet/AspNetCore/blob/b93bc433db66175d2b07b128ec9990f7a4dd7e1b/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs#L140 -L141

Tampaknya dua kemungkinan perbaikan adalah:

  1. Middleware CORS selalu menambahkan nilai "Saya sudah menjalankan" ke HttpContext.Items , atau:
  2. Middleware titik akhir _also_ memeriksa header origin jika metadata CORS ada di titik akhir, dan hanya mengeluarkan pengecualian untuk non-pemanggilan middleware CORS jika ada dalam permintaan HTTP.

Untuk Mereproduksi

  1. Konfigurasikan aplikasi ASP.NET Core MVC untuk menggunakan CORS.
  2. Tambahkan atribut [EnableCors(...)] ke metode pengontrol.
  3. Luncurkan aplikasi.
  4. Lakukan permintaan HTTP standar (misalnya dengan cURL) ke titik akhir.

Perilaku yang diharapkan

Permintaan berhasil jika tidak ada header permintaan HTTP origin yang disediakan.

Konteks tambahan

.NET Core SDK (reflecting any global.json):
 Version:   3.0.100-preview4-011204
 Commit:    621575bab1

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17763
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.0.100-preview4-011204\

Host (useful for support):
  Version: 3.0.0-preview4-27612-09
  Commit:  64e9c3e1cd
Done area-mvc bug

Komentar yang paling membantu

Untuk pratinjau4, solusi yang mungkin termasuk:

1) Memiliki middleware yang menetapkan nilai dalam HttpContext.Items setelah UseCors()

```C#
aplikasi.UseCors();

app.Use((konteks, selanjutnya) =>
{
context.Items["__CorsMiddlewareInvoked"] = true;
kembali berikutnya();
});


2) Disable the check in `EndpointRouting`:
```C#
services.AddRouting(r => r.SuppressCheckForUnhandledSecurityMetadata = true);

Yang pertama lebih disukai karena tidak menghapus centang untuk aplikasi yang salah dikonfigurasi.

Semua 3 komentar

Masalah ditemukan sebagai bagian dari membuat komit ini ke aplikasi kotak pasir sederhana: https://github.com/martincostello/api/pull/109/commits/a40a99f2dbb82d17ce6cc7cde5e13bc400d78137

cc @pranavkm

Untuk pratinjau4, solusi yang mungkin termasuk:

1) Memiliki middleware yang menetapkan nilai dalam HttpContext.Items setelah UseCors()

```C#
aplikasi.UseCors();

app.Use((konteks, selanjutnya) =>
{
context.Items["__CorsMiddlewareInvoked"] = true;
kembali berikutnya();
});


2) Disable the check in `EndpointRouting`:
```C#
services.AddRouting(r => r.SuppressCheckForUnhandledSecurityMetadata = true);

Yang pertama lebih disukai karena tidak menghapus centang untuk aplikasi yang salah dikonfigurasi.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat