使用ajaxSetup beforeSend的基本认证是打破SignalR连接(Using ajax

2019-09-01 01:04发布

我有基本认证固定一个的WebAPI其被应用于使用AuthorizationFilterAttribute整个API。 我也有SignalR集线器坐在我的几个阿比控制器。

除了这一点我有一个网页,利用我的WebAPI的。 该网页主要是写在骨干网,所以为了使呼叫我的安全的WebAPI,我已经添加了以下的jQuery

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

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

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调用。

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

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

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

Answer 1:

我以前没有提及的是,我有发回正确的标头进来到我的WebAPI的任何请求DelegatingHandler。 这完全适用于任何请求我的WebAPI,但我错误地认为,这也将适用于SignalR请求。

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

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


将查询字符串

$.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));

另外...

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

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

在这一过程中,我要离开SignalrBasicAuthFilterAttribute类承担,用于授权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认证?


Answer 2:

我认为这个问题的真正解决方案将确保“授权”是允许的头部的一部分(访问控制允许报头)从“谈判”请求signalR响应返回。

你可以在你的web.config一样,这种可能性注册的头。

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Headers" value="Authorization" />
  </customHeaders>
</httpProtocol>


文章来源: Using ajaxSetup beforeSend for Basic Auth is breaking SignalR connection