Cách bật CORS trong ASP.net Core WebAPI


188

Những gì tôi đang cố gắng làm

Tôi có API Web lõi ASP.Net được lưu trữ trên Gói miễn phí Azure (Mã nguồn: https://github.com/killerrin/Port portfolio -Backend ).

Tôi cũng có một trang web khách hàng mà tôi muốn sử dụng API đó. Ứng dụng khách sẽ không được lưu trữ trên Azure mà thay vào đó sẽ được lưu trữ trên trang Github hoặc trên một dịch vụ lưu trữ web khác mà tôi có quyền truy cập. Bởi vì điều này, tên miền sẽ không xếp hàng.

Nhìn vào điều này, tôi cần kích hoạt CORS ở phía API Web, tuy nhiên tôi đã thử mọi thứ trong vài giờ và nó đang từ chối hoạt động.

Cách tôi cài đặt Máy khách Nó chỉ là một ứng dụng khách đơn giản được viết bằng React.js. Tôi đang gọi API thông qua AJAX trong Jquery. Trang web React hoạt động để tôi biết không phải vậy. Cuộc gọi API Jquery hoạt động như tôi đã xác nhận trong Nỗ lực 1. Đây là cách tôi thực hiện các cuộc gọi

    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);
            }
        }
    });

Những gì tôi đã cố gắng


Cố gắng 1 - Cách 'phù hợp'

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

Tôi đã theo hướng dẫn này trên Trang web của Microsoft đến T, thử cả 3 tùy chọn kích hoạt nó trên toàn cầu trong Startup.cs, Thiết lập nó trên mọi bộ điều khiển và Thử trên mọi hành động.

Theo phương pháp này, Tên miền chéo hoạt động, nhưng chỉ trên một Hành động duy nhất trên một bộ điều khiển duy nhất (POST lên AccountContoder). Đối với mọi thứ khác, Microsoft.AspNetCore.Corsphần mềm trung gian từ chối đặt các tiêu đề.

tôi đã cài đặt Microsoft.AspNetCore.Cors qua NUGET và phiên bản là1.1.2

Đây là cách tôi thiết lập nó trong 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();

        ...
        ...
        ...
    }

Như bạn thấy, tôi đang làm mọi thứ như đã nói. Tôi đã thêm Cors trước MVC cả hai lần và khi nó không hoạt động, tôi đã cố gắng đặt [EnableCors("MyPolicy")]mọi bộ điều khiển như vậy

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

Cố gắng 2 - Brute Buộc nó

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

Sau vài giờ thử với lần thử trước, tôi đoán rằng tôi sẽ cố gắng đánh bại nó bằng cách cố gắng đặt các tiêu đề theo cách thủ công, buộc chúng phải chạy trên mọi phản hồi. Tôi đã làm theo hướng dẫn này về cách thêm thủ công vào mỗi phản hồi.

Đây là những tiêu đề tôi đã thêm

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

Đây là những tiêu đề khác tôi đã thử mà thất bại

.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")

Với phương pháp này, các tiêu đề Trang web chéo đang được áp dụng đúng cách và chúng hiển thị trong bảng điều khiển dành cho nhà phát triển của tôi và trong Postman. Tuy nhiên, vấn đề là trong khi nó vượt qua Access-Control-Allow-Originkiểm tra, webbrowser ném một sự phù hợp rít lên (tôi tin)Access-Control-Allow-Headers nói rõ415 (Unsupported Media Type)

Vì vậy, phương pháp vũ phu cũng không hoạt động


Cuối cùng

Có ai đã nhận được điều này để làm việc và có thể giúp một tay, hoặc chỉ có thể chỉ cho tôi đi đúng hướng?


BIÊN TẬP

Vì vậy, để thực hiện các lệnh gọi API, tôi đã phải ngừng sử dụng JQuery và chuyển sang XMLHttpRequestđịnh dạng Pure Javascript .

Cố gắng 1

Tôi đã xoay sở để có được Microsoft.AspNetCore.Corscông việc bằng cách làm theo câu trả lời của MindingData, ngoại trừ trong ConfigurePhương thức đặt app.UseCorstrước app.UseMvc.

Ngoài ra, khi được trộn với Giải pháp API Javascript options.AllowAnyOrigin()để hỗ trợ ký tự đại diện cũng bắt đầu hoạt động.

Cố gắng 2

Vì vậy, tôi đã quản lý để cho Nỗ lực 2 (buộc phải dùng nó) hoạt động ... với ngoại lệ duy nhất là Wildcard Access-Control-Allow-Originkhông hoạt động và do đó tôi phải tự đặt các tên miền có quyền truy cập vào nó.

Nó rõ ràng không lý tưởng vì tôi chỉ muốn WebAPI này được mở rộng cho mọi người, nhưng nó ít nhất hoạt động với tôi trên một trang web riêng biệt, điều đó có nghĩa là nó là một sự khởi đầu

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"));

2
Đối với 415 (Unsupported Media Type)vấn đề của bạn , đặt Content-Typetiêu đề yêu cầu thành application/json.
Technetium

5
Cảm ơn đã dành thời gian để viết một câu hỏi mô tả như vậy.
dùng1007074

1
Nếu bạn đang kiểm tra bằng Postman, hãy đảm bảo bạn đặt Origin thành * hoặc một cái gì đó cho tiêu đề yêu cầu, thì Nỗ lực số 1 sẽ hoạt động. Nếu không có tiêu đề này, Access-Control-Allow-Origin sẽ không được trả về trong tiêu đề phản hồi.
tala9999

Câu trả lời:


236

Vì bạn có chính sách CORS rất đơn giản (Cho phép tất cả các yêu cầu từ tên miền XXX), bạn không cần làm cho nó quá phức tạp. Hãy thử làm như sau trước (Một triển khai CORS rất cơ bản).

Nếu bạn chưa có, hãy cài đặt gói nuget CORS.

Install-Package Microsoft.AspNetCore.Cors

Trong phương thức ConfigureService của startup.cs của bạn, hãy thêm các dịch vụ CORS.

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

Sau đó, trong phương thức Cấu hình của startup.cs của bạn, hãy thêm vào như sau:

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();
}

Bây giờ cho nó đi. Các chính sách dành cho khi bạn muốn các chính sách khác nhau cho các hành động khác nhau (ví dụ: các máy chủ khác nhau hoặc các tiêu đề khác nhau). Ví dụ đơn giản của bạn, bạn thực sự không cần nó. Bắt đầu với ví dụ đơn giản này và điều chỉnh khi bạn cần từ đó.

Đọc thêm: http://dotnetcoretutorials.com/2017/01/03/eneac-cors-asp-net-core/


3
XMLHttpRequest không thể tải andrewgodfroyport portfolioapi.azurewebsites.net/api/Authentication . Trả lời yêu cầu preflight không vượt qua kiểm tra kiểm soát truy cập: Không có tiêu đề 'Kiểm soát truy cập-Cho phép-Xuất xứ' trên tài nguyên được yêu cầu. Do đó, nguồn gốc ' localhost: 3000 ' không được phép truy cập. Phản hồi có mã trạng thái HTTP 415.
killerrin

7
Điều này dường như không hoạt động, khi bạn đăng ký app.UseCors SAU `` app.UseMvc () `. Middleware được thực hiện theo thứ tự mà chúng được đăng ký
Tseng

24
sử dụng app.UseCors trước app.UseMvc, trong phương thức Configure dường như hoạt động. Đối với một số lý do, trình tự dường như có vấn đề.
MrClan

1
Đối với tôi, vấn đề lớn nhất của CORS trong 2.0 là nó không cho biết điều gì sai, chỉ âm thầm không đặt tiêu đề CORS. Lưu ý : hãy nhớ thêm tất cả các tiêu đề cần thiết của bạn vào chính sách nếu không nó sẽ bị lỗi (tôi có loại nội dung). Một điều kỳ lạ đối với tôi là phần mềm trung gian CORS không xử lý yêu cầu phanh, chỉ thông báo trong nhật ký rằng nguồn gốc không được phép và .. Truyền yêu cầu thêm (thứ tự phần mềm trung gian là chính xác).
Andrii M4n0w4R

2
Tôi đã phải kích hoạt options.DisableHttpsRequirement();để bất kỳ thứ này hoạt động. Có vẻ như với các cài đặt https không được áp dụng.
Michael Brown

206
  • Trong ConfigureService thêm services.AddCors(); BEFORE services.AddMvc ();
  • Thêm UseCors trong Cấu hình

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

Điểm chính là thêm app.UseCors, trướcapp.UseMvc() .

Hãy chắc chắn rằng bạn khai báo chức năng CORS trước MVC để phần mềm trung gian kích hoạt trước khi đường dẫn MVC được kiểm soát và chấm dứt yêu cầu.

Sau khi phương thức trên hoạt động, bạn có thể thay đổi cấu hình ORIGIN cụ thể để chấp nhận các cuộc gọi api và tránh để API của bạn mở cho mọi người

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

Trong phương thức cấu hình, yêu cầu CORS sử dụng chính sách bạn vừa tạo:

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

Tôi vừa tìm thấy bài viết nhỏ gọn này về chủ đề - https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi


1
Điều này làm việc cho tôi. codeproject.com/Articles/1150023/ từ
hubert17

17
Điều này thực sự sẽ nhận được nhiều sự ủng hộ hơn như là một điểm "khởi đầu" tốt. Theo kinh nghiệm của tôi hơn 25 năm mã hóa, thật tuyệt khi biết cách mở ra lũ lụt để đảm bảo nó thực sự "hoạt động" và sau đó đóng / bảo vệ mọi thứ khi cần.
Indy-Jones

4
Chỉ cần đề cập đến điều này, ngược lại với Configure()thứ tự không thực sự quan trọng ở đây trongConfigureServices()
B12Toaster

Tôi đã sử dụng liên kết trong Trình đọc thêm và các bước đó đã giải quyết lỗi này. Tôi không chắc chắn những thay đổi này sẽ được đặt ở đâu (tôi nghĩ API). Liên kết đã xác nhận rằng chúng nên được đặt trong API. Cảm ơn đã giúp đỡ. Tôi đã hoàn toàn quay bánh xe của tôi với lỗi này.
Richard

Điều này hoạt động với Asp.Net Core 2.1 và quan trọng hơn với localhost
Michal Frystacky

28

Tôi đã tạo lớp trung gian riêng của mình, nó hoạt động với tôi, tôi nghĩ có gì đó không ổn với lớp trung gian lõi .net

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>();
    }
}

và sử dụng nó theo cách này trong startup.cs

app.UseCorsMiddleware();

Cách rất thanh lịch để chạy Access-Control-Cho phép-Origin.
Artur Poniedziałek

Điều này hoạt động trên WebAPI và MVC và không có phụ thuộc, Cảm ơn bạn!
Joe

Tôi đã hoài nghi về điều này cũng, nhưng nó đã làm việc cho tôi. Về cơ bản, tôi đã thử mọi phương pháp khác để thực hiện điều này mà tôi có thể tìm thấy trên internet, nhưng không có vấn đề gì máy chủ sẽ không phản hồi với các tiêu đề truy cập. Điều này đã làm việc tuyệt vời. Tôi đang chạy aspnetcore 2.1.
Jordan

Bạn chỉ nên trả lại tiêu đề cors nếu khách hàng gửi tiêu đề "Xuất xứ" trong yêu cầu. Trong CospMiddleware ban đầu, nó trông như thế này:if (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) return this._next(context);
Andrew Prigorshnev

Có thể "có gì đó không ổn với lớp trung gian lõi .net" vì bạn không thêm tiêu đề "Xuất xứ" khi kiểm tra nó với curl hoặc một cái gì đó như thế này. Trình duyệt tự động thêm tiêu đề này khi bạn thực hiện một yêu cầu trong mã js.
Andrew Prigorshnev

16

Trong trường hợp của tôi, chỉ getyêu cầu hoạt động tốt theo câu trả lời của MindingData. Đối với các loại yêu cầu khác, bạn cần viết:

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

Đừng quên thêm .AllowAnyHeader()


Đồng ý với Towhid rằng AllowAnyHeader () là cần thiết. Nó cho phép máy chủ nhận yêu cầu TÙY CHỌN nếu yêu cầu của HEADER thiếu một cái gì đó.
Rivon

. ALLowAnyHeader () đã làm điều đó cho tôi, tôi gặp vấn đề với phản hồi preflight.
takaz

11

Để mở rộng câu trả lời của user8266077 , tôi thấy rằng tôi vẫn cần cung cấp phản hồi TÙY CHỌN cho các yêu cầu preflight trong .NET Core 2.1-preview cho trường hợp sử dụng của tôi:

// 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);
  }
}

và sau đó kích hoạt phần mềm trung gian như vậy trong Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseMiddleware(typeof(CorsMiddleware));
  // ... other middleware inclusion such as ErrorHandling, Caching, etc
  app.UseMvc();
}

1
Tôi khuyên bạn nên thêm phần mềm trung gian theo cách đó:app.Use<CorsMiddleware>();
Albert221

Bạn có thể thay thế 2 ligne đó: bối cảnh.Response.StatusCode = (int) HttpStatusCode.OK; đang chờ bối cảnh.Response.WriteAsync (string.Empty); với một cách đơn giản: trở lại;
Hayha

1
Để mở rộng khi bạn mở rộng câu trả lời của @ user8266077: Xin lưu ý rằng nếu yêu cầu cho một số lý do khác không thành công, phần mềm trung gian này sẽ đưa ra một ngoại lệ và các tiêu đề sẽ không được đặt. Có nghĩa là ở frontend, nó vẫn sẽ giống như một vấn đề CORS mặc dù nó hoàn toàn khác. Tôi đã bỏ qua điều này bằng cách nắm bắt bất kỳ trường hợp ngoại lệ nào await _next(context)và đặt mã trạng thái và phản hồi theo cách thủ công nếu điều này xảy ra. Tôi cũng đã phải thêm "ủy quyền" vào Tiêu đề kiểm soát truy cập cho phép để yêu cầu preflight hoạt động khi thực hiện các yêu cầu từ phản ứng yêu cầu ủy quyền.
Adam

10
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {      
       app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()
            );
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
    }

. SetIsOrigin ALLowed ((máy chủ) => true) đã giải quyết nó cho tôi.
JensB

wow, vì vậy tôi hoàn toàn mong đợi bất kỳ câu trả lời nào khác sẽ hoạt động trước câu trả lời nhỏ này chỉ với 3 phiếu. nhưng tôi đã cố gắng từng người một cách tỉ mỉ, ... trong một ý thích bất chợt tôi đã đi cho bạn và, nó đã làm việc. cảm ơn bạn
roberto tomás

9

Tôi đã vật lộn với điều này trong NGÀY.

Cuối cùng tôi đã nhận nó để làm việc bằng cách di chuyển app.UseCors(CORS_POLICY);đến TOP của Configure().

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

Đảm bảo rằng bạn khai báo chức năng CORS trước> MVC vì các tiêu đề phải được áp dụng trước khi MVC hoàn thành yêu cầu.

<= Mặc dù ứng dụng của tôi không gọi UseMVC(), di chuyển UseCors()lên đầu đã khắc phục sự cố

Cũng thế:

  • Microsoft.AspNetCore.Corsđã từng là gói NuGet bắt buộc trong .Net Core 2 trở xuống; giờ đây nó tự động là một phần của Microsoft.AspNetCore trong .Net Core 3 trở lên.
  • builder.AllowAnyOrigin().AllowCredentials() các tùy chọn CORS hiện đang loại trừ lẫn nhau trong .Net Core 3 trở lên
  • Chính sách CORS dường như yêu cầu Angular gọi máy chủ với https. Một URL http dường như đưa ra lỗi CORS bất kể cấu hình CORS của máy chủ .Net Core. Ví dụ, http://localhost:52774/api/Contactssẽ đưa ra một lỗi CORS; chỉ cần thay đổi URL để https://localhost:44333/api/Contactslàm việc.

Ghi chú thêm :

Trong trường hợp của tôi, CORS sẽ không hoạt động cho đến khi tôi chuyển app.UseCors()lên trên app.UseEndpoints(endpoints => endpoints.MapControllers()).


2
Đây có thể là câu trả lời nếu bạn đang sử dụng Net Core 3. Cảm ơn vì đã cứu mạng tôi!
Canada Wan

2
"Với định tuyến điểm cuối, phần mềm trung gian CORS phải được cấu hình để thực thi giữa các lệnh gọi UseRouting và UseEndpoint. Cấu hình không chính xác sẽ khiến phần mềm trung gian ngừng hoạt động chính xác." đây docs.microsoft.com/en-us/aspnet/core/security/ Kẻ
Mark Schultheiss

"Với định tuyến điểm cuối, phần mềm trung gian CORS phải được cấu hình để thực thi giữa các lệnh gọi UseRouting và UseEndpoint. Cấu hình không chính xác sẽ khiến phần mềm trung gian ngừng hoạt động chính xác." đây docs.microsoft.com/en-us/aspnet/core/security/ Kẻ
Mark Schultheiss

7

Không có thủ tục nào ở trên giúp được và sau đó tôi đọc bài viết đã giải quyết vấn đề.

Dưới đây là mã.

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(); 
}

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

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

và trên đỉnh của hành động của tôi

[EnableCors("CorsPolicy")]

2
Đây có lẽ là một ý tưởng tồi: bạn không nên trộn phần mềm trung gian ( app.UseCors()) với [EnableCors()]trong cùng một ứng dụng. Bạn nên sử dụng cái này hoặc cái kia - nhưng không phải cả hai: docs.microsoft.com/en-us/aspnet/core/security/ trộm :Use the [EnableCors] attribute or middleware, not both in the same app.
FoggyDay 8/12/19

4

thử thêm jQuery.support.cors = true;trước cuộc gọi Ajax

Nó cũng có thể là dữ liệu mà bạn gửi tới API rất nguy hiểm,

hãy thử thêm hàm JSON sau đây

        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;
    };

sau đó trong dữ liệu của bạn: đối tượng thay đổi nó thành

    data: JSON.stringify({
        username: username,
        password: password
    }),

Cảm ơn bạn đã giúp đỡ. Chắc chắn sử dụng một phần của câu trả lời để tìm ra giải pháp cuối cùng sau khi kết hợp câu trả lời của mọi người
killerrin

4

Giải pháp đơn giản nhất là thêm

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

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

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

đến Startup.cs.


3

Tôi nghĩ rằng nếu bạn sử dụng phần mềm trung gian CORS của riêng mình, bạn cần chắc chắn rằng đó thực sự là yêu cầu CORS bằng cách kiểm tra tiêu đề gốc .

 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);
    }

Cảm ơn rât nhiều. Tôi gần như phát điên, tự hỏi tại sao Access-Control-Allow-Origintiêu đề không được máy chủ cấp. Trên thực tế tôi đã gửi yêu cầu qua Postman với Origintiêu đề. Điều này đã cứu ngày của tôi! (Hoặc ít nhất là buổi sáng của tôi;))
Paul Kertscher

2

Dựa trên nhận xét của bạn trong câu trả lời của MindingData, nó không liên quan gì đến CORS của bạn, nó hoạt động tốt.

Hành động điều khiển của bạn đang trả lại dữ liệu sai. HttpCode 415 có nghĩa là "Loại phương tiện không được hỗ trợ". Điều này xảy ra khi bạn chuyển định dạng sai cho bộ điều khiển (tức là XML cho bộ điều khiển chỉ chấp nhận json) hoặc khi bạn trả về một loại sai (trả lại Xml trong bộ điều khiển được khai báo là chỉ trả về xml).

Để sau này kiểm tra sự tồn tại của [Produces("...")]thuộc tính trên hành động của bạn


Cảm ơn bạn đã giúp đỡ. Đã thử một giải pháp mới và chơi với json được gửi đi và nó đã hoạt động sau khi tôi
xâu chuỗi

2

Đối với tôi, nó không liên quan gì đến mã mà tôi đang sử dụng. Đối với Azure, chúng tôi phải vào cài đặt của Dịch vụ ứng dụng, trên menu bên cạnh mục "CORS". Ở đó tôi phải thêm tên miền mà tôi yêu cầu. Khi tôi đã có nó, mọi thứ đều kỳ diệu.


2

Trong launchSinstall.json, trong iisSinstall, đặt nặc danhAuthentication thành true:

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

Sau đó, trong Startup.cs, bên dưới ConfigureService, trước services.AddMvc, thêm:

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

và sau đó, trong phương thức cấu hình, trước app.UseMvc () thêm:

app.UseCors("ApiCorsPolicy");

Điều này đã làm điều đó cho tôi, ban đầu tôi đã thiết lập dự án của mình cho Windows xác thực nhưng sau đó phải đổi nó thành ẩn danh, tôi đã cấu hình chính xác CORS nhưng cài đặt này trong launchSinstall.json là thủ phạm, cảm ơn bạn đã đăng bài này!.
HaRoLD

2

Tôi đang sử dụng .Net CORE 3.1 và tôi đã mất nhiều năm đập đầu vào tường với cái này khi tôi nhận ra rằng mã của tôi đã bắt đầu thực sự hoạt động nhưng môi trường gỡ lỗi của tôi đã bị hỏng, vì vậy đây là 2 gợi ý nếu bạn đang cố gắng khắc phục sự cố vấn đề:

  1. Nếu bạn đang cố gắng ghi nhật ký tiêu đề phản hồi bằng phần mềm trung gian ASP.NET, tiêu đề "Access-Control-Allow-Origin" sẽ không bao giờ hiển thị ngay cả khi nó ở đó. Tôi không biết làm thế nào nhưng nó dường như được thêm vào bên ngoài đường ống (cuối cùng tôi đã phải sử dụng wireshark để xem nó).

  2. .NET CORE sẽ không gửi "Kiểm soát truy cập-Cho phép-Xuất xứ" trong phản hồi trừ khi bạn có tiêu đề "Xuất xứ" trong yêu cầu của mình. Người đưa thư sẽ không tự động thiết lập điều này vì vậy bạn sẽ cần phải tự thêm nó.


1

Lõi .NET 3.1

Làm việc cho tôi và làm thế nào các tài liệu nói để làm điều đó:

trong lớp Khởi nghiệp:

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; 

Trong phương thức ConfigureService ():

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

Trong phương thức Configure ():

    app.UseCors(MyAllowSpecificOrigins);  

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



0

Tôi đã nhận được câu trả lời của MindingData ở trên, nhưng tôi phải sử dụng Microsoft.AspNet.Cors thay vì Microsoft.AspNetCore.Cors. Tôi đang sử dụng dự án API ứng dụng web .NetCore trong Visual Studio 2019


2
LƯU Ý: bạn không nên sử dụng Microsoft.AspNet.Cors trong ứng dụng ASP.Net Cor. Nếu bạn đang sử dụng .Net Core 3.0 trở lên, bạn không cần phải nhập bất kỳ gói NuGet nào cho CORS. Nếu bạn đang sử dụng .Net Core 2.3 trở xuống, thì bạn cần phiên bản Microsoft.AspNet.Cors phù hợp từ NuGet.
FoggyDay

0

Các

Microsoft.AspNetCore.Cors

sẽ cho phép bạn thực hiện CORS với các tính năng tích hợp, nhưng nó không xử lý yêu cầu TÙY CHỌN. Cách giải quyết tốt nhất cho đến nay là tạo ra một Middleware mới như được đề xuất trong bài viết trước. Kiểm tra câu trả lời được đánh dấu là đúng trong bài sau:

Bật tiêu đề TÙY CHỌN cho CORS trên API Web .NET Core


0

Cách đơn giản và dễ dàng để làm điều đó.

  1. Cài đặt gói

Install-Package Microsoft.AspNetCore.Cors

  1. Đặt mã dưới đây trong tệp startup.cs

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


0

Đây là mã của tôi :)

  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();
        });

0

Đây là cách tôi đã làm điều này.

Tôi thấy rằng trong một số câu trả lời họ đang đặt app.UserCors("xxxPloicy")và đặt[EnableCors("xxxPloicy")] vào bộ điều khiển. Bạn không cần phải làm cả hai.

Dưới đây là các bước.

Trong Startup.cs bên trong ConfigureService thêm đoạn mã sau.

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

Nếu bạn muốn áp dụng tất cả các dự án thì hãy thêm đoạn mã sau vào Phương thức cấu hình trong Startup.cs

app.UseCors("xxxPolicy");

Hoặc là

Nếu bạn muốn thêm nó vào các bộ điều khiển cụ thể thì hãy thêm mã kích hoạt như dưới đây.

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

Để biết thêm thông tin: xem cái này


0

Sử dụng Thuộc tính Hành động / Trình điều khiển tùy chỉnh để đặt các tiêu đề CORS.

Thí dụ:

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
    }
}

Sau đó, trên Trình điều khiển / Hành động API Web:

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

0

Chỉ cần thêm vào để trả lời ở đây, nếu bạn đang sử dụng app.UseHttpsRedirection()và bạn đang nhấn không phải cổng SSL hãy xem xét nhận xét này.


0

Tôi đã sử dụng blazor webassugging như là ứng dụng khách api và web asp.net lõi làm phụ trợ và cũng có vấn đề về cors.

Tôi tìm thấy giải pháp với các mã này:

Api lõi web ASP.Net của tôi Startup.cs ConfigureService và Configure phương thức các dòng đầu tiên trông như thế này:

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

 //other code below...
}

và phương thức Cấu hình của tôi:

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

thay đổi http://example.comvới tên miền khách hàng hoặc địa chỉ IP của bạn


-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(); ;
                    });
            });

Vui lòng chỉnh sửa câu trả lời của bạn để bao gồm và giải thích mã của bạn và nó khác với các câu trả lời khác như thế nào. Điều này sẽ làm cho bài đăng của bạn hữu ích hơn và có nhiều khả năng nó sẽ được nâng cấp :)
Das_Geek
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.