如何在ASP.net Core WebAPI中启用CORS?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (391)

我正在尝试做什么

我有一个Azure Free Plan托管的后端ASP.Net Core Web API(http://andrewgodfroyportfolioapi.azurewebsites.net/swagger/)(源代码:https//github.com/killerrin/Portfolio-Backend)。

我也有一个客户端网站,我想要使用该API。客户端应用程序不会托管在Azure上,而是托管在Github页面上或我有权访问的其他Web Hosting服务上。因此,域名不会排队。

考虑到这一点,我需要在Web API方面启用CORS,但是现在我几个小时都试过了几乎所有事情,而且它拒绝工作。

我如何拥有客户端安装程序 它只是一个用React.js编写的简单客户端。我在Jquery中通过AJAX调用API。React网站运作,所以我不知道它。Jquery API调用按我在尝试1中确认的方式工作。以下是我如何进行调用

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

我所尝试过的

尝试1 - “正确”的方式

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

我已经在Microsoft网站上将此教程转换为T,尝试在Startup.cs中全局启用它的所有3个选项,在每个控制器上设置它并在每个Action上尝试它。

遵循这种方法,跨域可以工作,但只能在单个控制器上的单个Action上(POST到AccountController)。对于其他一切,Microsoft.AspNetCore.Cors中间件拒绝设置标题。

Microsoft.AspNetCore.Cors通过NUGET 安装,版本是1.1.2

这是我如何在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();

        ...
        ...
        ...
    }

正如你所看到的,我正在按照所说的去做。我在两次MVC之前都添加了Cors,而当这些都不起作用时,我试图将[EnableCors("MyPolicy")]每个控制器都放在这里

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

尝试2 - 暴力强制它

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

在经历了几个小时的尝试之后,我想我会尝试通过尝试手动设置标题强制它,强制它们在每个响应中运行。我在本教程后面做了如何为每个响应手动添加标题的内容。

这些是我添加的标题

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

这些是我尝试失败的其他头文件

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

使用这种方法,跨站点头文​​件正在被正确应用,并且显示在我的开发者控制台和Postman中。然而,问题是,虽然它通过Access-Control-Allow-Origin检查,网页浏览器将引发嘘声像合上(我相信)Access-Control-Allow-Headers说明415 (Unsupported Media Type)

所以暴力方法也不起作用

最后

有没有人得到这个工作,并可以伸出援助之手,或者只是能够指引我正确的方向?

编辑

所以为了让API调用通过,我不得不停止使用JQuery并切换为纯Javascript的XMLHttpRequest格式。

尝试1

我设法Microsoft.AspNetCore.Cors按照MindingData的回答开始工作,除了在ConfigureMethod app.UseCors之前放置之前app.UseMvc

另外,当与Javascript API解决方案混合使用时options.AllowAnyOrigin(),通配符支持也开始起作用。

尝试2

所以我设法得到尝试2(暴力强制它)工作...唯一的例外是通配符Access-Control-Allow-Origin不起作用,因此我必须手动设置有权访问它的域。

它显然并不理想,因为我只是想让这个WebAPI向所有人开放,但它至少在单独的站点上为我工作,这意味着它是一个开始

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"));
提问于
用户回答回答于

因为你有一个非常简单的CORS策略(允许来自XXX域的所有请求),所以你不需要使它变得如此复杂。首先尝试下面的内容(CORS的一个非常基本的实现)。

如果你还没有安装CORS nuget软件包。

Install-Package Microsoft.AspNetCore.Cors

在startup.cs的ConfigureServices方法中,添加CORS服务。

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

然后在startup.cs的Configure方法中,添加以下内容:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseCors(
        options => options.WithOrigins("http://example.com").AllowAnyMethod()
    );

    app.UseMvc();
}

现在放手吧。当需要针对不同操作的不同策略(例如不同的主机或不同的标题)时,策略适用。举个简单的例子,你真的不需要它。从这个简单的例子开始,并根据需要调整。

进一步阅读:http : //dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/

用户回答回答于
  • configureservices中添加 services.AddCors(); BEFORE services.AddMvc();
  • 配置中添加UseCors app.UseCors(builder => builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); app.UseMvc();

重点是添加app.UserCors,之前app.UserMvc()

确保在MVC之前声明CORS功能,以便中间件在MVC管道获得控制并终止请求之前触发。

扫码关注云+社区