【问题标题】:CORS in .NET Core.NET Core 中的 CORS
【发布时间】:2017-02-23 21:10:03
【问题描述】:

我正在尝试以这种方式在 .NET Core 中启用 CORS:

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
                                                                    .AllowAnyMethod()
                                                                     .AllowAnyHeader()));     
        services.AddMvc();            
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseCors("AllowAll");

        app.UseMvc(routes =>
         {
             routes.MapRoute(
                 name: "default",
                 template: "{controller=Home}/{action=Index}/{id?}");
         });

    }
}

但是,当我使用 Angular 2 向我的应用程序发送请求时,我得到了著名的

“请求中没有“Access-Control-Allow-Origin”标头 资源。”

错误信息。

我也在使用 Windows 身份验证 + WebListener。 如果我与邮递员核对,唯一的响应标头是:

内容长度 →3533 内容类型→应用程序/json; 字符集=utf-8 日期 →2016 年 10 月 14 日星期五 12:17:57 GMT 服务器 →Microsoft-HTTPAPI/2.0

所以肯定还是配置有问题。有什么建议吗?

如果我删除注释掉的行,它可以工作,但我需要 Windows 身份验证 :-(

        var host = new WebHostBuilder()
            .UseWebListener()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            //.UseWebListener(options => options.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.NTLM)
            .Build();

【问题讨论】:

标签: c# web cors .net-core


【解决方案1】:

我刚刚在 Core 3.1 中解决了我的 Cors 问题。我几乎在关注所有示例和文档。不幸的是,在我为 AddPolicy 部分中的构建器执行 .Build() 之前,没有任何效果。

        services.AddCors(options => {
            options.AddPolicy(
                name: OrginPolicyKey, 
                builder => builder.WithOrigins("http://localhost:3000")
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .Build() // <--- This right here
            );
        });

另外,其他人提到在你的路由和 UseMvc 的其余部分之前调用 UseCors(OrginPolicyKey)。这是正确的,我看到在路线部分破坏它之后放置 UseCors。以下是我的设置方式。

        app.UseCors(OrginPolicyKey); // <--- First

        // Then routing stuff..
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints
                .MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}"
                );
        });

谁知道需要建造建筑商 ;D

【讨论】:

  • 这个问题困扰了很久,不知道是怎么回事。这解决了我所有的问题。非常感谢!
  • 就我而言,调用 UseCors 的顺序解决了我的问题,它必须在 UseRouting() 之前调用,谢谢。
【解决方案2】:

这实际上是 dotnet core 中的一个错误。

尝试在“配置”方法中添加 cors 策略。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseRouting();
        app.UseCors(option =>
            option.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                );
    }

【讨论】:

    【解决方案3】:

    将此部分添加到appsettings.json

    "App": {
      "CorsOrigins": "http://yourdomain"
    }
    

    services.AddCors(options => {
      options.AddPolicy(DefaultCorsPolicyName, builder => {
    
       builder.WithOrigins(
         _appConfiguration["App:CorsOrigins"]
           .Split(",", StringSplitOptions.RemoveEmptyEntries)
           .Select(o => o.RemovePostFix("/"))
           .ToArray()
       ).SetIsOriginAllowedToAllowWildcardSubdomains()
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials();
      });
    });
    

    注意:appsettings.json 中的App:CorsOrigins 可以包含多个地址,并以逗号分隔。

    【讨论】:

    • .SetIsOriginAllowedToAllowWildcardSubdomains() 在启用 IIS 和 Windows 身份验证的情况下为我完成了这项工作
    【解决方案4】:

    我在我的应用程序中遇到了 CORS 问题。我觉得我正确地实现了逻辑,但仍然出现 Access-Control-Allow-Origin 403 错误。我尝试了上面提到的所有设置,但没有任何效果。

    我后来发现我的问题与 CORS 无关。我实现了一个自定义属性

    [Route("v1/[Controller]")]
    [ServiceFilter(typeof(MyCustomFilterAttribute))]
    public class MySpecialListsController 
    

    对控制器的调用正确地进入了 OnActionExecuting 方法

    public override void OnActionExecuting(ActionExecutingContext context)
    

    过滤器中的逻辑引发异常并显示为 CORS 403 错误。

    【讨论】:

    • 对,问题可能不是 CORS,您可以启用日志并查看您的方法是否存在问题
    【解决方案5】:

    只需在 StartUp 类的 ConfigureService 方法中添加即可

    services.AddCors ();
    

    这在启动类的配置方法中,它会正常工作

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

    在 .Net Core 中启用 CORS 无需添加任何其他内容

    【讨论】:

      【解决方案6】:

      在 ASPNET CORE 2.0 中,以下内容适用于我

         public void ConfigureServices(IServiceCollection services)
          {
      
              services.Configure<MvcOptions>(options =>
              {
                  options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
              });
              services.AddCors(options =>
              {
                  options.AddPolicy("AllowSpecificOrigin",
                      builder => builder.WithOrigins("http://localhost:5000").AllowAnyHeader()
                      .AllowAnyMethod());
              });
      
              services.AddMvc()
          }
      
          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
          public void Configure(IApplicationBuilder app, IHostingEnvironment env)
          {
      
              loggerFactory.AddConsole();
              loggerFactory.AddDebug(LogLevel.Information);
      
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
      
              // Shows UseCors with named policy.
              app.UseCors("AllowSpecificOrigin");
      
              app.UseStaticFiles();
              app.UseAuthentication();
      
      
              app.UseMvcWithDefaultRoute();
          }
      }
      

      【讨论】:

        【解决方案7】:

        文档遗漏的是 .AllowAnyMethod() 的重要性。如果不存在,可怕的 No 'Access-Control-Allow-Origin' 将继续困扰您。在您的代码中,它在那里,所以我猜您错过了在 jour 客户端应用程序中设置正确的标题。

        我个人通过允许所有人让它工作:

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

        我的 Angular 发布功能如下:

        post(model) {
        
            let headers = new Headers({
              'Content-Type':'application/json; charset=utf-8;' 
              ,'Accept':'*/*'
            });
        
        
            let options = new RequestOptions({ headers: headers });
            let body = JSON.stringify(model);
        
            return this.http.post(
              'http://localhost:58847/api/TestPost', body, options)
              .map((response: Response) => {
                let res = response.json();
                return res;
              }
            );
        }
        

        之后,您会通过指定原点等方式逐步提升。

        【讨论】:

        • app.UseCors(builder =&gt; builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); 为我工作。谢谢斯特凡!
        【解决方案8】:

        假设您有答案,但为了搜索者的利益,我在.NET Core Cors 上的标准教程中遇到了同样的问题。

        遇到的许多错误之一:

        XMLHttpRequest 无法加载 localhost:64633/api/blogs。回复 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此,不允许使用 Origin 'localhost:56573' 使用权。响应的 HTTP 状态代码为 500。

        玩了之后,下面的代码工作了。完整的课程贴在下面,以帮助理解去哪里。

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;
        using Microsoft.AspNetCore.Builder;
        using Microsoft.AspNetCore.Hosting;
        using Microsoft.Extensions.Configuration;
        using Microsoft.Extensions.DependencyInjection;
        using Microsoft.Extensions.Logging;
        using Microsoft.EntityFrameworkCore;
        using Microsoft.AspNetCore.Cors.Infrastructure;
        
        namespace NetCoreWebApiTesting
        {
            public class Startup
            {
                public Startup(IHostingEnvironment env)
                {
                    var builder = new ConfigurationBuilder()
                        .SetBasePath(env.ContentRootPath)
                        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
        
                    if (env.IsEnvironment("Development"))
                    {
                        // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
                        builder.AddApplicationInsightsSettings(developerMode: true);
                    }
        
                    builder.AddEnvironmentVariables();
                    Configuration = builder.Build();
                }
        
                public IConfigurationRoot Configuration { get; }
        
                // This method gets called by the runtime. Use this method to add services to the container
                public void ConfigureServices(IServiceCollection services)
                {
                    // Add framework services.
                    services.AddApplicationInsightsTelemetry(Configuration);
        
                    services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling =
                                                                    Newtonsoft.Json.ReferenceLoopHandling.Ignore);
        
                    // ********************
                    // Setup CORS
                    // ********************
                    var corsBuilder = new CorsPolicyBuilder();
                    corsBuilder.AllowAnyHeader();
                    corsBuilder.AllowAnyMethod();
                    corsBuilder.AllowAnyOrigin(); // For anyone access.
                    //corsBuilder.WithOrigins("http://localhost:56573"); // for a specific url. Don't add a forward slash on the end!
                    corsBuilder.AllowCredentials();
        
                    services.AddCors(options =>
                    {
                        options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());
                    });
                }
        
                // 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();
        
                    app.UseApplicationInsightsRequestTelemetry();
        
                    app.UseApplicationInsightsExceptionTelemetry();
        
                    app.UseMvc();
        
                    // ********************
                    // USE CORS - might not be required.
                    // ********************
                    app.UseCors("SiteCorsPolicy");
                }
            }
        }
        

        要使用它,您可以在控制器或方法上添加EnableCorsAttribute。例如

        [EnableCors("SiteCorsPolicy")]
        [Route("api/[controller]")]
        public class BlogsController : Controller
        {
        
        }
        

        // POST api/value
        [EnableCors("SiteCorsPolicy")]
        [HttpPost]
        public HttpResponseMessage Post([FromBody]Blog value)
        {
            // Do something with the blog here....
        
            var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
            return msg;
        
        }
        

        当我使用以下代码调用它时(使用标准 js/jQuery 以便于复制和粘贴),通信停止被拒绝。

        function HandleClick() {
        
            var entityData = {
                "blogId": 2,
                "url": "http://blog.com/blog1",
                "posts": [
                {
                    "postId": 3,
                    "title": "Post 1-1",
                    "content": "This is post 1 for blog 1",
                    "blogId": 2
                },
                {
                    "postId": 4,
                    "title": "Post 1-2",
                    "content": "This is post 2 for blog 1",
                    "blogId": 2
                }
                ]
            };
        
            $.ajax({
                type: "POST",
                url: "http://localhost:64633/api/blogs",
                async: true,
                cache: false,
                crossDomain: true,
                data: JSON.stringify(entityData),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (responseData, textStatus, jqXHR) {
                    var value = responseData;
                },
                error: function (responseData, textStatus, errorThrown) {
                    alert('POST failed.');
                }
            });
        }
        

        【讨论】:

        • // for a specific url. Don't add a forward slash on the end ...老兄...怎么会有人想出来大声笑...谢谢!
        • 您可以使用@Tanver Hasan 的回答中所述的 options.Filters.Add (new CorsAuthorizationFilterFactory("SiteCorsPolicy")) 而不是手动添加每个控制器上的 EnableCors 属性
        • 您的解决方案刚刚拯救了我的一天。非常感谢您的样品。
        • 请注意,您不能同时允许任何来源和任何凭据。如果您需要任何凭据,则需要指定来源
        【解决方案9】:

        @HockeyJ 的答案是对的,但如果需要,您可以做一些更简洁的事情。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        
            //Or if you want to chose what to include
            services.AddMvcCore()
                    .AddCors()
                    (...)
        }
        
        
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            //Cors
            app.UseCors(builder =>
            {
                builder.AllowAnyHeader();
                builder.AllowAnyMethod();
                builder.AllowCredentials();
                builder.AllowAnyOrigin(); // For anyone access.
                //corsBuilder.WithOrigins("http://localhost:56573"); // for a specific url.
             });
        }
        

        【讨论】:

        • 运行良好,但不允许同时使用 AllowCredentials 和 AllowAnyOrigin
        【解决方案10】:

        这种方式可以正常工作,只是在 angular2 上用 .net core 试了一下。 OP 遇到的问题是这不适用于 Windows 身份验证。我假设用于 Windows 身份验证的中间件在请求通过之前发生,在这种情况下它会中断。最好的办法是在配置中处理完 cors 中间件后,看看是否有办法启用 windows auth 中间件。

        那么顺序是

        App.UseCors()

        App.UseWindowsAuth()

        App.UseMVC()

        它们必须按此顺序发生才能正常工作。

        public void ConfigureServices(IServiceCollection services)
            {
                services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
                                                                            .AllowAnyMethod()
                                                                             .AllowAnyHeader()));     
                services.AddMvc();            
            }
        
            public void Configure(IApplicationBuilder app)
            {
                app.UseCors("AllowAll");
        
                app.UseMvc(routes =>
                 {
                     routes.MapRoute(
                         name: "default",
                         template: "{controller=Home}/{action=Index}/{id?}");
                 });
        
            }
        

        【讨论】:

        • 我遇到了同样的问题,但使用的是 JWT。将顺序改为:app.UseCors() app.UseJwtBearerAuthentication() app.UseMvc() 解决了,谢谢!
        • 我遇到了同样的问题,但似乎无法解决@user1527312
        • 天哪,这已经为我修好了!谢谢!
        • 这是最简单的解决方案。在尝试使用 Angular 6 获得简单的“Hello World”解决方案时为我工作
        • 如前所述,它被称为的顺序为我修复了它
        猜你喜欢
        • 2020-03-20
        • 2019-10-18
        • 2018-10-13
        • 2020-11-02
        • 2018-01-16
        • 2020-07-30
        • 2020-05-22
        • 2018-10-31
        • 2019-05-24
        相关资源
        最近更新 更多