连接Auth令牌并将其传递给启用了CORS的SignalR集线器

时间:2014-08-04 14:13:54

标签: oauth-2.0 signalr cors asp.net-web-api2

我有三个ASP.NET WebAPI端点:

  1. 身份服务器,生成承载令牌(serverA.com);
  2. 带集线器的SignalR服务器(serverB.com);
  3. 一些带有简单ASP.NET MVC视图和SignalR JS客户端脚本(serverC.com)的端点。
  4. 所有三台服务器都使用OAuth2中间件作为Auth机制。 Microsoft.Owin.Cors也已配置。 服务器仅使用HTTPS请求。 SignalR v2.2.0安装在serverB.com上。

    我可以成功地从serverC.com向serverA.com发出跨域请求以获取持有者令牌,但实际上,我不知道如何在连接到serverB.com时传递身份验证令牌

    到目前为止,我找到了两种方法:

    1. 将身份验证令牌作为查询字符串传递(不安全);
    2. 将此设置应用于jQuery.ajax

      $。ajaxSetup({ beforeSend:function(xhr){     xhr.setRequestHeader('tokenKey','tokenValue'); }});

    3. 但它迫使SignalR仅使用长轮询。

      是否有其他方式发送auth令牌(不在查询字符串中),以便OAauth BearerAuthorizationProvider可以使用和验证它?也许,cookies,标题或任何其他方式?

      更新

      为两个环境设置CORS中间件以允许所有数据并接受凭据。

      这是我的OWIN中间件:

      var requestUri = context.Request.Uri.AbsolutePath;
      if (string.Equals(requestUri, authRoute, StringComparison.OrdinalIgnoreCase))
      {
           if (!context.Request.Headers.ContainsKey("Authorization") || string.IsNullOrEmpty(context.Request.Headers["Authorization"]))
           {
                 context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
           }
           else
           {
                 context.Response.Cookies.Append("BearerToken", context.Request.Headers["Authorization"]);
           }
        }
        else
        {
            await Next.Invoke(context);
        }
      

      然后我做第一个Ajax请求:

      $.ajax({
              url: self.communicationHubUrl + '/authenticate',
              type: 'post',
              cache: false,
              crossDomain: true,
              beforeSend: function(xhr) {
                   xhr.setRequestHeader('Authorization', self.accessToken);
             });
      

      中间件将头文件中的身份验证令牌设置为响应cookie。

      然后我调用hub.Start,以便SignalR开始发送ajax请求。

      但由于某些原因我不太明白,只有当我通过$ .ajaxSetup为所有ajax请求启用xhr.withCredentials = true时才会在请求中出现cookie

              $.ajaxSetup({
                  xhrFields: {
                      withCredentials: true
                  }
              });
      

      如果没有此设置,请求不包含Cookie。另一方面,我认为强制所有ajax请求启用此类设置并不是一个好的决定。

      此外,我在Oauth中间件中遇到了奇怪的行为:当来自signalR的请求来而不是401 Unauthorized时,我没有调用ValidateIdentity方法,我得到了聋人校长。

1 个答案:

答案 0 :(得分:1)

我认为将认证令牌放入cookie是最好的选择。与ajaxSetup选项不同,cookie与EventSource和WebSocket请求一起发送。

您可能需要向SignalR服务器(serverB.com)添加一些中间件,以便在启动SignalR连接之前POST auth令牌时设置相应的cookie。