【问题标题】:Error thrown when calling HubConnection.Start: StatusCode: 401, ReasonPhrase: 'Incoming principal is null'调用 HubConnection.Start 时引发错误:StatusCode: 401, ReasonPhrase: 'Incoming principal is null'
【发布时间】:2017-01-21 05:25:15
【问题描述】:

我将 SignalR 与我的 WebApi 应用程序一起使用,并且效果很好:客户端使用 WebSocket 传输连接到集线器,并且用户通过一些自定义中间件身份验证进行身份验证。

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

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”)之前,我有这个传入的主体为空问题。所以我在这里添加了它,然后我在我的其他应用程序中为集线器添加了一个自定义授权类:

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;
    }
}

当然,我的 hub 有 headers 属性:

[HeadersAuth]
public class MyHub : Hub
{
    // Hub logic
}

但是,运行此命令后,我仍然收到传入的主体为空错误。然后我读到您不能将自定义 http 标头与 WebSockets 一起使用,这就是我将 new LongPollingTransport() 放在上面的 hubConn.Start 调用中的原因。但这似乎并没有改变任何东西,至少不是我得到的错误。

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

只是添加更多我尝试过的内容:

  • 我故意弄错了身份验证字符串令牌,以查看是否收到不同的错误,但我仍然收到传入的主体为空。

  • 我意识到我的集线器的OnConnected() 覆盖方法调用了一个方法,该方法尝试将传入主体与this.Context.User 一起使用,而不检查它是否为空。我删除了它以及任何其他试图在集线器中使用传入主体的东西,但不幸的是它仍然给出了同样的错误。

【问题讨论】:

    标签: c# signalr


    【解决方案1】:

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

    还应该注意的是,在我开始工作后,我无法从代理进行集线器方法调用,因为它没有被授权这样做。为了解决这个问题,我添加了

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    

    HeadersAuthAttribute 课程,我从here 获得。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 1970-01-01
      相关资源
      最近更新 更多