【问题标题】:AspNetCore.SignalR 2.1 and CORSAspNetCore.SignalR 2.1 和 CORS
【发布时间】:2018-06-19 12:55:31
【问题描述】:

我正在将我们的 SignalR-Service 迁移到新的 AspNetCore.SignalR(2.1 预览版),现在我遇到了 CORS 问题。我永远不会从同一来源访问该服务,因此我通常需要禁用 CORS。

我有以下 CORS 政策

services.AddCors(
            options => options.AddPolicy("AllowCors",
                builder =>
                {
                    builder
                        .AllowAnyOrigin()
                        .AllowCredentials()
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                })
        );

(我的来自不同来源的 WebApi-Controller 调用在这些策略下运行良好)

使用用于 AspNetCore (AspNetCore.SignalR.Server) 的 SignalR 的旧预览包,我没有遇到任何问题,但现在,我的测试客户端得到了一些 http-405,这似乎是 CORS 的问题。

可能有针对 SignalR 的额外 CORS 配置,还是我需要允许其他配置?

编辑: 我创建了一个新的/干净的示例项目,没有任何特殊的中间件来检查错误是否发生在这里并且确实发生了。

示例 Web 应用程序 |启动.cs

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.Extensions.Options;
using WebApplication1.HUBs;

namespace WebApplication1
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(
                options => options.AddPolicy("AllowCors",
                    builder =>
                    {
                        builder
                            .AllowAnyOrigin()
                            .AllowCredentials()
                            .AllowAnyHeader()
                            .AllowAnyMethod();
                    })
            );
            services.AddMvc();
            services.AddSignalR(options =>
            {
            });
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("AllowCors");
            app.UseMvc();
            app.UseSignalR(routes =>
            {
                routes.MapHub<TestHub>("/test");
            });
        }
    }
}

示例 Winforms 应用程序

        private HubConnection _hubConnection;
    private void button1_Click(object sender, EventArgs e)
    {
        var connection = new HubConnectionBuilder().WithUrl("http://localhost:63771/test")
            .WithConsoleLogger()
            .WithTransport(Microsoft.AspNetCore.Sockets.TransportType.WebSockets)
            .Build();
        connection.StartAsync();
    }

示例 Winforms 应用程序控制台输出

fail: Microsoft.AspNetCore.Sockets.Client.HttpConnection[8]
   01/10/2018 15:25:45: Failed to start connection. Error getting negotiation response from 'http://localhost:63771/test'.
System.Net.Http.HttpRequestException: Response status code does not indicate success: 405 (Method Not Allowed).
   bei System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   bei Microsoft.AspNetCore.Sockets.Client.HttpConnection.<Negotiate>d__42.MoveNext()

【问题讨论】:

  • 您是否在 StartupConfigure 方法中将值“AllowCors”传递给 app.UseCors("AllowCors");?这应该就是你所需要的。
  • 你在Configure(IApplicationBuilder app, IHostingEnvironment env)Startup.cs 中有这个吗:app.UseCors("AllowCors");
  • 我应该更清楚;我评论中的代码行不是您需要的all。您需要它,以及 ConfigureServices 方法中已有的代码。他们一起工作。
  • 是的,我已经使用了我创建的策略。我的 WebApi-Controller 已经在接受来自 X-Origins 的调用,因此我可以确定策略本身可以正常工作(对于 REST-Controller)但不适用于 SignalR 连接。
  • @slxSlashi 你修过吗?

标签: c# asp.net-core cors asp.net-core-signalr


【解决方案1】:

这对我来说不起作用,而一个稍微不同的版本就起作用了 -

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

  app.UseSignalR(routes => { routes.MapHub<ChatHub>("/chatHub"); });
  app.UseMvc();
}

【讨论】:

  • 在搜索了大约 5 个小时的答案(包括此页面上的所有其他答案)之后,此选项对我有用。谢谢。
  • @Ian Grainger,谢谢!我有相同的配置,保存一项。通过在您的示例中添加 SetIsOriginAllowed,使我的客户端 Web 应用程序连接到我的 api 应用程序(集线器)
【解决方案2】:

尝试像这样将app.UseSignalR() 移动到app.UseMvc() 之上

app.UseCors("AllowCors");
app.UseSignalR(routes =>
    {
        routes.MapHub<TestHub>("/test");
    });
app.UseMvc();

【讨论】:

  • 我花了一天时间试图弄清楚这一点。你能解释一下为什么需要这样做吗?我猜这是因为 UseMvc 方法可能已经依赖 SignalR 路由来“注册”
  • @MichaelJ.Heier 我讨厌看到未回答的问题,所以:UseMvc 在以这种方式调用时配置了默认路由,因此它需要是集合中的最后一个路由以允许其他路由优先当映射请求时......在这种情况下,异常是由 MVC 处理 SignalR 应该处理的东西引起的。
  • 现在已弃用此答案。推荐的方法是在端点中进行这种映射:endpoints.MapHub("/test");
【解决方案3】:

我遇到了同样的问题,我在客户端使用 reactjs。 将版本从使用"@aspnet/signalr-client" 更改为"@aspnet/signalr" 解决了我的问题

【讨论】:

  • 在 Angular 5 应用程序上为我工作。
【解决方案4】:

升级到 preview1 时,你必须将你的包升级到 @aspnet/signalr

注意:用于 JavaScript 的 SignalR 客户端库的先前预览 被命名为@aspnet/signalr-client。这已被弃用 预览 1。

source: Github readme

【讨论】:

    【解决方案5】:

    我解决了这个问题。

    client-package 和 server-package 不处于确切的 subversion 状态。 它是 2.1-preview3210 和 2.1-preview3209(示例编号)。

    服务器包经常发布到 nuget 提要,但客户端包 (npm) 不会。所以我自己克隆了最新的 git repo 并构建了库,它可以工作。

    您不会再遇到问题了,客户端包现在是最新的。

    【讨论】:

      【解决方案6】:

      如果您要将项目迁移到 asp.net core 版本 3.x,您可以像这样从 Configure 方法升级 routing

      app.UseCors("AllowCors");
      
      app.UseEndpoints(endpoints =>
      {
          endpoints.MapControllerRoute(
              name: "default",
              pattern: "{controller=Home}/{action=Index}/{id?}");
      
          endpoints.MapHub<TestHub>("/test");
      });
      

      app.UseMvcapp.UseSignalR 将替换为 app.UseEndpointsapp.UseSignalR 也不能再使用了,因为:

      此方法已过时,将在未来版本中删除。

      【讨论】:

      • 我也需要使用OData,在UseEndpoints中不能使用MapODataServiceRoute
      猜你喜欢
      • 2019-10-17
      • 2019-03-18
      • 2021-01-26
      • 2021-03-22
      • 2019-08-29
      • 2021-07-25
      • 2021-11-14
      • 2017-08-23
      • 1970-01-01
      相关资源
      最近更新 更多