在Azure上使用CORS的SignalR无法正常工作

时间:2014-04-29 21:17:10

标签: azure signalr cors

我无法让Signalr在Azure上支持CORS。我创建了MSDN Getting Started示例聊天程序,将其部署到Azure并确保其正常运行。然后我按照说明如何在SignalR Hubs API Guide - JavaScript Client中启用CORS,即我更改了Startup.cs以使用Microsoft.Owin.Cors并设置

map.UseCors(CorsOptions.AllowAll);

并在Win8上使用IE11进行了尝试。

Signalr / IE正在发送CORS预检请求,如下所示:

Request OPTIONS /signalr/signalr/negotiate?connectionData=%5B%7B%22name%22%3A%22ommhub%22%7D%5D&clientProtocol=1.3&_=1398784789992 HTTP/1.1
Accept  */*
Origin  https://my.devserver.com
Access-Control-Request-Method   GET
Access-Control-Request-Headers  content-type, accept, x-requested-with
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; LCJB; rv:11.0) like Gecko
Host    mytestsite.azurewebsites.net
Content-Length  0
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache

和Azure正在返回几乎看起来正确的东西:

Response    HTTP/1.1 200 OK
Allow   OPTIONS, TRACE, GET, HEAD, POST
Content-Length  0
Server  Microsoft-IIS/8.0
Public  OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By    ASP.NET
Set-Cookie  ARRAffinity=6115ee2c8e2594676e68d4f0ee51035a2;Path=/;Domain=mytestsite.azurewebsites.net
Date    Tue, 29 Apr 2014 15:23:43 GMT

但是浏览器在此之后永远不会发送任何内容(它应该请求连接)。我怀疑这可能是因为预检响应不包括Access-Control-Allow-Origin标头。

网上有很多相互矛盾的信息。有没有人成功地在Azure上使用CORS处理SignalR中心?如果你在那里,请告诉我们你是如何做到的。

4 个答案:

答案 0 :(得分:0)

我没有时间调试Signalr代码,但我想出了一个解决方法。

我通过同一域中的URL代理Signalr请求,从而加载另一个服务(正确处理CORS)。一旦OPTIONS预检请求由其他服务处理,IE允许所有进一步的请求在没有预检的情况下发生。

答案 1 :(得分:0)

对我来说,以下方法有效:

app.Map("/signalr", map =>
{
    map.UseCors(_corsOptions.Value);
    //map.UseCors(CorsOptions.AllowAll); // also ok but perhaps a little bit too open
    var hubConfiguration = new HubConfiguration
    {
        EnableDetailedErrors = false
    };

    map.RunSignalR(hubConfiguration);
});

使用_corsOptions.Value,如下所示:

private static Lazy<CorsOptions> _corsOptions = new Lazy<CorsOptions>(() =>
{
    return new CorsOptions
    {
        PolicyProvider = new CorsPolicyProvider
        {
            PolicyResolver = context =>
            {
                var policy = new CorsPolicy();
                policy.Origins.Add("http...");
                policy.AllowAnyMethod = true;
                policy.AllowAnyHeader = true;
                policy.SupportsCredentials = true;
                return Task.FromResult(policy);
            }
        }
    };
});

但不幸的是,这或多或少是您提到的样本中的代码不适合您。

你的web.config怎么样?它是干净的还是有像

这样的CORS之类的东西
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
            </customHeaders>
        </httpProtocol>

我不记得是否应该在那里。所以,如果它不起作用,它就在那里,删除它,否则你可以尝试添加它......

答案 2 :(得分:0)

如果它可以提供帮助,在我这边,我用过:

  • map.UseCors(CorsOptions.AllowAll);
  • web.config
  • 中没有customHeaders
  • 从我的Azure CORS Allowed-Origin中取出*(是的,我不得不把它取下来停止从我当地的js客户端获取跨域错误)

答案 3 :(得分:0)

要在部署到azure 时让信号灯正常工作,我必须使用:

  1. web.config中没有customHeaders
  2. 将cors与corsoptions一起使用
  3. appBuilder.SetDataProtectionProvider
  4. 关于2:内部启动配置:

     appBuilder.Map("/signalr", map =>
     {
        var corsOptions = new Microsoft.Owin.Cors.CorsOptions
        {
           PolicyProvider = new CorsPolicyProvider
           {
              PolicyResolver = context => ResolvePolicy()
           }
       };
       map.UseCors(corsOptions);
     }
    

    使用ResolvePolicy():

    private Task<System.Web.Cors.CorsPolicy> ResolvePolicy() {
    
            var corsPolicy = new System.Web.Cors.CorsPolicy()
            {
                AllowAnyMethod = true,
                AllowAnyHeader = true,
                SupportsCredentials = true
            };
    
            corsPolicy.Origins.Add("http://ng2a-hneu-web-ui.azurewebsites.net");
            corsPolicy.Origins.Add("http://localhost:3000");
    
            return Task.FromResult(corsPolicy);
        }
    

    关于3:在startup.cs内,配置()

    appBuilder.SetDataProtectionProvider(new MachineKeyProtectionProvider());
    

    以下是gist的链接。

    我在官方信号器github 上找到了解决方案。
    请点击此链接:ASP.NET 5 app in Azure doesn't work with SignalR

    仅在部署到Azure时才会出现此问题。在开发模式下,使用ISS表达似乎一切正常。

    添加允许的来源时非常重要的一点是不要用斜杠对它们进行后缀。

    corsPolicy.Origins.Add("http://xxxx**/**"); //incorrect
    corsPolicy.Origins.Add("http://xxx); //correct