首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在ASP.net核心WebAPI中启用CORS

如何在ASP.net核心WebAPI中启用CORS
EN

Stack Overflow用户
提问于 2017-06-06 08:15:00
回答 35查看 339.4K关注 0票数 273

我正在尝试做什么?

我有一个托管在ASP.Net免费计划(源代码:https://github.com/killerrin/Portfolio-Backend)上的后端Azure Core Web。

我也有一个客户网站,我想让消费者的API。客户端应用程序不会托管在Azure上,而是会托管在Github页面或我可以访问的其他Web托管服务上。正因为如此,域名不会排成一行。

考虑到这一点,我需要在Web API端启用CORS,但是我已经尝试了几个小时,但它拒绝工作。

我是如何设置客户端的,这只是一个用React.js写的简单的客户端。我在Jquery中通过AJAX调用API。React站点可以工作,所以我知道不是这样的。Jquery API调用按照我在尝试1中确认的方式工作。

代码语言:javascript
复制
    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

我跟随微软网站上的这篇教程,尝试了在Startup.cs中全局启用它的所有3个选项,在每个控制器上设置它,并在每个操作中尝试它。

按照这种方法,跨域可以工作,但只能在单个控制器上的单个操作上工作(POST到AccountController)。对于其他任何事情,Microsoft.AspNetCore.Cors中间件都拒绝设置头部。

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

下面是我如何在Startup.cs中设置它

代码语言:javascript
复制
    // 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")]放在每个控制器上

代码语言:javascript
复制
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller

尝试2-暴力强迫它

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

在尝试了之前的几个小时后,我想我应该尝试手动设置头文件,强制它们在每次响应时运行。我是在学习如何手动向每个响应添加报头的教程之后完成此操作的。

这些是我添加的头文件

代码语言:javascript
复制
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")

这些是我尝试过的其他头文件,但都失败了

代码语言:javascript
复制
.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检查,但fit浏览器在Access-Control-Allow-Headers上抛出了(我相信) 415 (Unsupported Media Type)

所以暴力方法也不起作用

最终

有没有人能帮上忙,或者能给我指出正确的方向?

编辑

因此,为了让应用程序接口调用通过,我不得不停止使用JQuery,并切换到纯Javascript XMLHttpRequest格式。

尝试1

通过遵循MindingData的答案,我设法让Microsoft.AspNetCore.Cors工作,除了在Configure方法中将app.UseCors放在app.UseMvc之前。

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

尝试2

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

这显然不是很理想,因为我只是想让这个WebAPI对每个人都开放,但它至少在一个单独的站点上对我有效,这意味着它是一个开始

代码语言:javascript
复制
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"));
EN

回答 35

Stack Overflow用户

回答已采纳

发布于 2017-06-06 09:16:12

因为您有一个非常简单的CORS策略(允许来自XXX域的所有请求),所以您不需要把它搞得这么复杂。首先尝试执行以下操作(CORS的一个非常基本的实现)。

如果您尚未安装CORS nuget包,请安装它。

代码语言:javascript
复制
Install-Package Microsoft.AspNetCore.Cors

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

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(); // Make sure you call this previous to AddMvc
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

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

代码语言:javascript
复制
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();
}

现在试一试吧。当您想要为不同的操作(例如,不同的主机或不同的标头)使用不同的策略时,可以使用策略。对于您的简单示例,您真的不需要它。从这个简单的示例开始,然后根据需要进行调整。

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

票数 299
EN

Stack Overflow用户

发布于 2017-08-10 03:53:14

在services.AddMvc();之前添加ConfigureServices中的

  • services.AddCors();

  • Add UseCors in Configure

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

要点是在app.UseMvc()之前添加app.UseCors

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

在上述方法起作用后,您可以更改它,配置一个特定的源来接受api调用,并避免让您的API对任何人开放

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

    services.AddMvc();
}

在configure方法中,告诉CORS使用刚刚创建的策略:

代码语言:javascript
复制
app.UseCors("ApiCorsPolicy");
app.UseMvc();

我刚找到一篇关于这个主题的紧凑文章- https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi

票数 268
EN

Stack Overflow用户

发布于 2017-08-23 23:55:26

我创建了适合我的中间件类,我认为.net核心中间件类有问题

代码语言:javascript
复制
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>();
    }
}

并以这种方式在startup.cs中使用

代码语言:javascript
复制
app.UseCorsMiddleware();
票数 37
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44379560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档