使用ajaxSetup beforeSend的基本认证是打破SignalR连接基本、ajaxSetup、beforeSend、SignalR

2023-09-10 16:13:46 作者:低调成本性i

我有固定与基本验证一个的WebAPI这是适用于使用AuthorizationFilterAttribute整个API。我也有SignalR集线器坐在我的几个阿比控制器。

I have a WebApi secured with Basic Auth which is applied to the entire Api using a AuthorizationFilterAttribute. I also have SignalR Hubs sitting on several of my Api Controllers.

除了这一点我有一个网页,它利用我的WebAPI的。该网页主要是写的骨干,所以为了打电话到我的安全的WebAPI,我已经添加了以下的jQuery

Alongside this I have a web page which makes use of my WebApi. The web page is mostly written in Backbone, so in order to make calls to my secured WebApi, I have added the following jquery

$.ajaxSetup({
    beforeSend: function (jqXHR, settings) {
        jqXHR.setRequestHeader('Authorization', 'Basic ' + Token);
        return true;
    }
});

这适用于与我的API控制器进行通信,但加入上述code打破了连接到我的SignalR集线器,具体为:

This works for communicating with my Api Controllers, but adding the above code has broken the connection to my SignalR Hubs, specifically:

XMLHttpRequest cannot load http://localhost:50000/signalr/negotiate?_=1366795855194. 
Request header field Authorization is not allowed by Access-Control-Allow-Headers. 

删除 jqXHR.setRequestHeader()行恢复我SignalR集线器连接,但打破了API调用。

Removing the jqXHR.setRequestHeader() line restores my SignalR Hub connection but breaks the Api calls.

鉴于上述情况,我可以做一些哈克,只设置请求头如果被提出的要求并不是/ signalr但这只是觉得脏...

Given the above, I could do something hacky and only set the request header if the request being made isn't to /signalr but that just feels dirty...

有没有解决这个一个更清洁的方式?

Is there a cleaner way around this?

难道我只是在做一些愚蠢?有没有其他人在跑这个?

Am I just doing something silly? Has anyone else ran in to this?

推荐答案

我没提到之前,我有一个DelegatingHandler发回正确的标题为即将在我的WebAPI的请求。这完全适用于我的WebAPI的任何请求,但我错误地认为,这也将适用于SignalR请求。

What I didn't mention before is that I have a DelegatingHandler which sends back the correct Headers to any request coming in to my WebApi. This works perfectly for any requests to my WebApi but I wrongly assumed that this would also apply to SignalR requests.

由于SignalR依赖于几个不同的运输方式,它似乎并没有合理的假设我有机会获得授权头摆在首位 - 他们不是所有的WebSockets实现,例如要求(看到这里)

As SignalR relies on several different transport methods, it doesn't seem reasonable to assume I have access to Authorization headers in the first place - they're not a requirement of all WebSockets implementations for example (see here)

我目前的解决方案是利用SignalR的HubPipeline(详细这里)。利用这一点,我相信我可以通过基本认证证书的查询字符串,写一个单独的模块来处理授权的SignalR请求:

My current solution has been to make use SignalR's HubPipeline (detailed here). Using this, I believe I can pass the Basic Auth credentials in a query string and write a separate module for handling Authorization for the SignalR requests:

传递的查询字符串

$.connection.hub.qs = "auth=" + MyBase64EncodedAuthString;

过滤器

public class SignalrBasicAuthFilterAttribute: Attribute, IAuthorizeHubConnection {

    public bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) {
      var authString = request.QueryString["auth"];

      // ... parse, authorize, etc ...

      return true;
    }

}

注册过滤器

var globalAuthorizer = new SignalrBasicAuthFilterAttribute();
GlobalHost.HubPipeline.AddModule(new AuthorizeModule(globalAuthorizer, globalAuthorizer));

另外...

需要注意的是,因为它不是一个可靠的假设发送Authorization头与SignalR的请求,因为上述理由,我还是过滤我的$ .ajaxSetup只影响的非SignalR 的请求:

Note that because it's not a reliable assumption to send an Authorization header with SignalR requests, for the aforementioned reasons, I am still filtering my $.ajaxSetup to only affect non-SignalR requests:

$.ajaxSetup({
    beforeSend: function (jqXHR, settings) {
        if (settings.url.indexOf("/signalr") == -1)
            jqXHR.setRequestHeader('Authorization', 'Basic ' + Token);
        return true;
    }
});

在这样做,我要离开SignalrBasicAuthFilterAttribute类承担用于授权SignalR请求全部责任。

In doing this, I'm leaving SignalrBasicAuthFilterAttribute class to take on full responsibility for Authorizing SignalR requests.

延伸阅读:

http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx http://eworldproblems.mbaynton.com/2012/12/signalr-hub-authorization/ SignalR一个控制器内的认证? http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx http://eworldproblems.mbaynton.com/2012/12/signalr-hub-authorization/ SignalR authentication within a Controller?