CORS政策不想与SignalR和ASP.NET Core一起使用

时间:2019-02-22 09:13:24

标签: angular asp.net-core cors signalr angular7

我的ASP.NET核心API和Angular Client有问题。我想实现SignalR在API和Angular之间建立连接。 cors策略已在我们的客户端和API上激活,因为我们已经可以使用我们的客户端从API检索数据。但是现在的问题是,当我尝试使用SignalR时,收到CORS POLICY错误:

  

在以下位置访问XMLHttpRequest   原产地的“ http://localhost:50501/CoordinatorHub/negotiate”   “ http://localhost:4200”已被CORS政策屏蔽:对   预检请求未通过访问控制检查:否   请求中存在“ Access-Control-Allow-Origin”标头   资源。

但是我们的API的Startup.cs内部已经有cors政策,就像这样:

在ConfigureServices方法中:

services.AddCors(options =>
{
    options.AddPolicy("AllowSpecificOrigin",
        builder => 
        builder.WithOrigins("http://localhost:4200/")
            .AllowCredentials()
            //.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .SetIsOriginAllowedToAllowWildcardSubdomains());
});

在Configure方法中:

app.UseCors("AllowSpecificOrigin");

在我们的客户端中,我们只想尝试在API和客户端之间建立连接,就像这样:

this.hubConnection.start({withCredentials: false}).then(() => 
     this.hubConnection.invoke('send', 'Hello'));

7 个答案:

答案 0 :(得分:6)

注意,它可以应用于.net core 3.1

正如Microsoft文档中所述,它似乎不起作用 docs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Preceding code ommitted.
    app.UseRouting();

    app.UseCors();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    // Following code ommited.
}

警告

对于端点路由,必须将CORS中间件配置为 在对UseRouting和UseEndpoints的调用之间执行。不正确的 配置将导致中间件停止正常运行。

但是如果您首先移动UseCors(),您的应用程序将按预期运行,因此工作代码将

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
                options.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//place your useCors here 
    app.UseCors();
    app.UseRouting();


    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    // Following code ommited.
}

答案 1 :(得分:5)

被接受的答案对我没有用,所以我决定在这里写下对我有用的内容。如果有人偶然发现同一问题。

在Angular 9上使用signalR时,我在本地测试中遇到了相同的问题。

我通过将Asp NET Core(3.1)应用程序URL从https切换为http来解决了该问题。如果您使用的是Visual Studio,

  1. 只需右键单击项目属性->调试。
  2. 取消选中启用SSL

Asp Net core Project

也不要忘记在angular App中更改URL的端口。因此,基本上角度应用中的URL会是这样的

this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:50782/hub").build();

Configure方法中的相关代码是这样的

app.UseHttpsRedirection();
app.UseStaticFiles();

   
app.UseRouting();
app.UseCors("_myAllowSpecificOrigins");

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapHub<ChatHub>("/hub");
});

以及我在您的configureServices方法中关注的

    services.AddRazorPages();

    services.AddCors(options =>
        {
            options.AddPolicy("_myAllowSpecificOrigins",
                builder =>
                {
                    builder.WithOrigins("https://localhost:4200")
                           .AllowAnyHeader()
                           .AllowAnyMethod()
                           .SetIsOriginAllowed((x) => true)
                           .AllowCredentials();
                });
        });
    
   services.AddSignalR();

希望这会有所帮助!

更新

如果您只是在本地计算机上玩弄样本,还可以尝试以here

的安全模式运行chrome。

在我的Mac上,我只是从终端运行命令

open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security

有了这个,您应该可以运行样本而不必担心CORS了

答案 2 :(得分:2)

在启动配置类中尝试以下操作:

app.Map("/CoordinatorHub/negotiate", map =>
{
    map.UseCors(CorsOptions.AllowAll);
    var hubConfiguration = new HubConfiguration 
    {
        // You can enable JSONP by uncommenting line below.
    // EnableDetailedErrors = true,
        // EnableJSONP = true

    };
    map.RunSignalR(hubConfiguration);
});

答案 3 :(得分:1)

我已根据此link

解决了我的问题

将此阻止代码添加到服务中

services.AddCors(options => options.AddPolicy("CorsPolicy",
        builder =>
        {
            builder.AllowAnyHeader()
                   .AllowAnyMethod()
                   .SetIsOriginAllowed((host) => true)
                   .AllowCredentials();
        }));

并在配置应用程序时添加此阻止代码

app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
        {
            routes.MapHub<General>("/hubs/general");
        });

答案 4 :(得分:1)

我遇到了一个类似的问题,我为此苦苦挣扎了 6 个小时。

原来我的起源结尾有一个斜线。

所以代替:

.WithOrigins("https://aaa.azurewebsites.net/")

使用:

.WithOrigins("https://aaa.azurewebsites.net")

我无法理解为什么最后的斜线没有被去掉。

答案 5 :(得分:0)

最近,我遇到了.Net Core 3.1的相同问题,当我在Azure应用服务中进行部署时,问题开始了,最后能够使用以下代码解决问题。

我在Startup.cs文件的ConfigureServices函数中使用以下代码

services.AddCors(options =>
        {
            var corsUrls = Configuration.GetSection("App:CorsOrigins").Value.ToString()
                      .Split(",", StringSplitOptions.RemoveEmptyEntries)
                             .Select(o => o.Trim('/'))
                             .ToArray();
            options.AddPolicy("CorsPolicy",
            builder =>
            {
                builder.WithOrigins(corsUrls)
                       .AllowAnyHeader()
                       .AllowAnyMethod()
                       .AllowCredentials();
            });
        });

然后在“配置”功能中添加以下代码

app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
  {
    endpoints.MapControllers();
    endpoints.MapHub<WebhookHub>("/Webhook");
  });

不要忘记在appsetting.json文件中添加以下部分

"App": {
"CorsOrigins": "https://myservice.com" }

答案 6 :(得分:0)

在.Net Core 3.1+和Angular 8+版本以及android 19+ api级别的signalR上进行了测试,并且也在iOS设备上工作

.Net核心代码

public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy", builder => builder.WithOrigins("http://localhost:4200")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials()
                );
            });


            services.AddRazorPages();
            services.AddAccessTokenService();
            services.AddSignalR()
                 .AddHubOptions<ChatHub>(options => options.EnableDetailedErrors = true)
                 .AddJsonProtocol(options =>
                 {
                     options.PayloadSerializerOptions.PropertyNamingPolicy = null;
                  }); ;
            services.AddSingleton<IUserIdProvider, NameUserIdProvider>();

        }



public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseCors("CorsPolicy");

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapRazorPages();
                endpoints.MapHub<ChatHub>("/chathub");
            });

        }

-角度代码替换为url和token(可选部分),并且可以正常工作

public startConnection = () => {
  this.hubConnection = new signalR.HubConnectionBuilder()
                          .withUrl(this.url,{ accessTokenFactory: () => this.token},)
                          .build();

  this.hubConnection
    .start()
    .then(() => console.log('Connection started'))
    .catch(err => console.log('Error while starting connection: ' + err))
}

   ngOnInit(): void {
      this.startConnection();

  }