SignalR跨域连接与自托管和身份验证

Mat*_*rds 13 cors signalr owin

我在使用OWIN自托管SignalR时遇到了CORS问题,这只有在我尝试启用身份验证时才会发生.

我在网络浏览器中收到的错误是:

XMLHttpRequest无法加载http://.../signalr/negotiate?[snip] Origin-Control-Allow-Origin不允许

只有在我使用此答案中的方法在我的自托管服务器中启用身份验证时才会发生这种情况:

public void Configuration(IAppBuilder app)
{
  var listener = (HttpListener)app.Properties[typeof(HttpListener).FullName];
  listener.AuthenticationSchemes = AuthenticationSchemes.Ntlm; 

  app.MapHubs(new HubConfiguration { EnableCrossDomain = true });
} 
Run Code Online (Sandbox Code Playgroud)

如果我注释掉该AuthenticationSchemes行,那么CORS就可以了(我已经检查了这些说明中的所有内容).如果我使用其他身份验证方案而不是NTLM,我会遇到同样的问题.

使用Fiddler检查发生了什么,启用身份验证,我看到从服务器返回的必要CORS头:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:[我的服务器]

但是,一旦我启用身份验证,我得到一个401响应,缺少这些标头.所有请求都有必要的Origin标题.

在检查了SignalR 源代码之后,它看起来像是正在设置标头,但可能在启用了身份验证的HttpListener情况下发送了初始的401响应而没有点击此代码.

所以我认为我的问题是:如何在其身份验证协议的协商中HttpListener包含Access-Control-Allow-Origin标题?

FXb*_*ers 4

通过允许预检请求匿名访问,我已经获得了 NTLM 身份验证,可以与 OWIN 中自托管的跨域 signalR 一起使用。

需要做的是创建一个委托来选择身份验证方案,该方案会查找预检请求标头,并允许它们匿名通过。所有其他请求将使用 NTLM。

public void Configuration(IAppBuilder appBuilder)
{
    var listener = (HttpListener)appBuilder.Properties[typeof(HttpListener).FullName];
    listener.AuthenticationSchemeSelectorDelegate += AuthenticationSchemeSelectorDelegate;
}

private AuthenticationSchemes AuthenticationSchemeSelectorDelegate(HttpListenerRequest httpRequest)
{
    if (httpRequest.Headers.Get("Access-Control-Request-Method")!=null) 
        return AuthenticationSchemes.Anonymous;
    else 
        return AuthenticationSchemes.Ntlm;
}
Run Code Online (Sandbox Code Playgroud)