C# 调用HubConnection时引发错误。开始:状态代码:401,原因短语:';传入主体为空';

C# 调用HubConnection时引发错误。开始:状态代码:401,原因短语:';传入主体为空';,c#,signalr,C#,Signalr,我在WebApi应用程序中使用signar,这很好:客户端使用WebSocket传输连接到集线器,用户通过一些自定义中间件身份验证进行身份验证 我正在尝试从另一个后端应用程序(.NET client)连接到此集线器,为此,我建立一个集线器连接并创建一个集线器代理,然后调用集线器方法: string auth = "someEncryptedValue" HubConnection hubConn = new HubConnection("myUrl"); hubConn.Headers.Add(

我在WebApi应用程序中使用signar,这很好:客户端使用WebSocket传输连接到集线器,用户通过一些自定义中间件身份验证进行身份验证

我正在尝试从另一个后端应用程序(.NET client)连接到此集线器,为此,我建立一个集线器连接并创建一个集线器代理,然后调用集线器方法:

string auth = "someEncryptedValue"
HubConnection hubConn = new HubConnection("myUrl");
hubConn.Headers.Add("myauthtoken", auth);
IHubProxy proxy = hubConn.CreateHubProxy("hubName");
Task t = Task.Run(() => hubConn.Start(new LongPollingTransport()));
t.WaitAndUnwrap // An extension method
hubProxy.Invoke("SendMessage", message);
调用
t.WaitAndUnwrap()
时会引发异常(扩展方法不是问题所在)。在添加http头标记(当然,它实际上不是文本字符串“someEncryptedValue”)之前,我遇到了这个传入主体为null的问题。因此,我在这里添加了这一点,然后在另一个应用程序中为中心添加了一个自定义授权类:

public class HeadersAuthAttribute : AuthorizeAttribute
{
    public override bool AuthroizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
    {
        string auth = request.Headers["myauthtoken"];
        if (auth == "someEncryptedValue") //again, this is actually more complex than shown here
        {
            return true;
        }
        else
        {
            // Need to check if the incoming principal is authenticated in case
            // the connection to the hub is being made the normal way through the
            // WebApi instead of the proxy using http headers
            return request.User?.Identity?.IsAuthenticated ?? false;
        }
        return false;
    }
}
当然,我的集线器具有headers属性:

[HeadersAuth]
public class MyHub : Hub
{
    // Hub logic
}
然而,在运行这个之后,我仍然得到传入主体为null的错误。然后我读到您不能将自定义http头与WebSocket一起使用,这就是为什么我将
new LongPollingTransport()
放在上面的
hubConn.Start
调用中。但这似乎没有改变任何事情,至少没有改变我所犯的错误

有人知道会发生什么吗?如果我能用实际的集线器和授权调试代码,这样我就可以看到在调用
hubConn.Start
时发生了什么。有没有办法检查http头的设置和获取是否正确?如果错误是关于传入主体为null,那么身份验证就是问题所在吗?它可能是代码中试图找到用户的另一部分吗?我不知道该怎么办,因为这个集线器连接是从.NET客户端建立的。另外,我知道正在调用
headersauthdattribute
类,并且在正常使用WebSocket连接到集线器时正确使用了该类,因为它会进入else情况,检查
IIdentity
是否经过身份验证

只是想补充一下我尝试过的内容:

  • 我故意使auth字符串标记出错,以查看是否出现其他错误,但我仍然得到传入主体为null

  • 我意识到我的hub的
    OnConnected()
    override方法调用了一个方法,该方法尝试将传入主体与
    this.Context.User
    一起使用,而不检查它是否为null。我删除了它以及其他试图在中心中使用传入主体的内容,但不幸的是,它仍然给出了相同的错误


    • 我发现了问题所在。这与集线器身份验证无关,正如我在完成这篇文章时所怀疑的那样。发生的事情是,我的启动文件调用了app.ConfigureAuth,但这最终导致OWIN中间件管道中的一些自定义授权,用于检查传入主体是否为null。我把它拿出来做信号连接

      还应该注意的是,在我完成这项工作之后,我无法从代理进行hub方法调用,因为它没有这样做的授权。为了解决这个问题,我补充道

      public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
      

      到我从中获得的
      HeaderAuthAttribute
      类。

      我找出了问题所在。这与集线器身份验证无关,正如我在完成这篇文章时所怀疑的那样。发生的事情是,我的启动文件调用了app.ConfigureAuth,但这最终导致OWIN中间件管道中的一些自定义授权,用于检查传入主体是否为null。我把它拿出来做信号连接

      还应该注意的是,在我完成这项工作之后,我无法从代理进行hub方法调用,因为它没有这样做的授权。为了解决这个问题,我补充道

      public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
      
      到我从中获得的
      headersauthtribute