将 signalR 通知中心部署到 IIS 时出现 CORS 错误

CORS errors when deploying signalR notification Hub to IIS

我的 signalR Hub 可以 运行 在安全端口 44311 上的 VS2019 调试模式下正常,但是一旦我将它发布到我的开发箱上的本地 IIS,../hub/negotiate 就会失败并显示 CORS policy异常。

ex.在调试模式下,IIS托盘

signalr Hub 正常启动:


现在进入我的本地 Window 10 IIS 设置,我在其中部署了 signalR Hub 项目:

  1. 我设置了 https 绑定
  2. 我成功设置了 SSL 证书,并设置了需要 SSL 复选框:
  3. 我重新启动我的 IIS 网站,并浏览 44311 进行测试

但果然,我的应用无法连接到 HUB:

Access to XMLHttpRequest at 'https://localhost:44311/hub/negotiate?negotiateVersion=1' from origin 'http://localhost:4200' has been blocked by CORS policy:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

POST https://localhost:44311/hub/negotiate?negotiateVersion=1 net::ERR_FAILED


然而在我的代码中我注入了CORS:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NotificationHub.Hubs;
namespace NotificationHub
{
    public class Startup
    {
        readonly string MyAllowedSpecificOrigins = "_myAllowedSpecificOrigins";

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy(name: MyAllowedSpecificOrigins,
                                  builder => {
                                      builder.WithOrigins("https://localhost:4200", "localhost:4200")
                                        .SetIsOriginAllowedToAllowWildcardSubdomains()
                                        .AllowAnyHeader()
                                        .AllowAnyMethod()
                                        .AllowCredentials()
                                        .SetIsOriginAllowed((host) => true);
                                  }
                                  );
            });
           
            services.AddSignalR(hubOptions => {
                hubOptions.EnableDetailedErrors = true;
                hubOptions.KeepAliveInterval = System.TimeSpan.FromMinutes(1000);
            });            
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseCors(MyAllowedSpecificOrigins);

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // app.UseSession();
            app.UseEndpoints(endpoints =>
            {           
                endpoints.MapHub<Notifications>("/hub", options => {
                    options.Transports = HttpTransportType.WebSockets | HttpTransportType.LongPolling;
                });
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Notification HUB has started!");                    
                });
            });
        }
    }
}

目前我不确定这是编码问题(即未正确设置 CORS)还是部署问题。

感谢帮助。

谢谢。

更新

根据下面的建议答案,我的 CORS 问题在部署到 IIS 时得到解决:

  1. 为 IIS 安装 cors:https://www.iis.net/downloads/microsoft/iis-cors-module
  2. 添加以下 <customHeaders> 到 web.config

但是,我在 IIS 部署模式下仍然无法成功连接到集线器 (http://localhost:55271/hub/negotiate?negotiateVersion=1 throws 404 not found);但是调试工作正常。

<httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
          <add name="Access-Control-Allow-Credentials" value="true" />
          <add name="Access-Control-Request-Headers" value="User-Agent,Content-Type,Authorization,X-RequestDigest,X-ClientService-ClientTag,XMLHttpRequest,x-requested-with" />
          <add name="Access-Control-Allow-Headers" value="User-Agent,Content-Type,Authorization,X-RequestDigest,X-ClientService-ClientTag,XMLHttpRequest,x-requested-with" />
          <add name="Access-Control-Request-Method" value="GET,POST,HEAD,OPTIONS" />
        </customHeaders>
      </httpProtocol>

确保您启用了 iis .net 功能。在 iis 中为站点启用目录浏览:

1)启动 IIS 管理器。

2)在 IIS 管理器中,展开服务器名称,展开网站,然后 select 网站。

3)在“功能”视图中,双击“目录浏览”。

4) 在“操作”窗格中,单击“启用”。

在 web.config 文件中添加以下代码:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="http://my-external-app-domain.com" />
    <add name="Access-Control-Allow-Credentials" value="true" />
    <add name="Access-Control-Request-Headers" value="User-Agent,Content-Type,Authorization,X-RequestDigest,X-ClientService-ClientTag" />
    <add name="Access-Control-Request-Method" value="GET,POST,HEAD,OPTIONS" />
  </customHeaders>
</httpProtocol>
</system.webServer>

使用 web 平台安装程序或从下面在 iis 中安装 cors 模块 link:

https://www.iis.net/downloads/microsoft/iis-cors-module

更新:

在下面添加到 web.config:

HttpRequest,x-requested-with 在“Access-Control-Request-Headers”中都需要。此外,我插入了 header name="Access-Control-Allow-Headers" ,其值与 Request-Headers 相同。