14

我在使用 OWIN 自托管 SignalR 时遇到了 CORS 问题,这仅在我尝试启用身份验证时发生。

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

XMLHttpRequest 无法加载http://.../signalr/negotiate?[snip] Origin ... Access-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 });
} 

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

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

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

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

在检查了 SignalR源代码后,它看起来像正在设置标头,但大概启用了身份验证,HttpListener发送初始 401 响应而没有点击此代码。

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

4

2 回答 2

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;
}
于 2013-11-11T01:42:43.017 回答
3

I presume you're using Chrome, which very unhelpfully tells you that these headers are missing and that this is the problem, when actually you have probably just forgot to set your XMLHttpRequest's withCredentials property to true.

If you're using jQuery you can do this for all requests with:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
  options.xhrFields = { withCredentials: true };
});

You also need to do the right thing with OPTIONS requests as in the other answer.

于 2014-12-05T13:03:55.717 回答