10

这个问题与另一个线程有关,您可以在此处阅读:使用 SignalR 进行表单身份验证,我在用户dfowler 的帮助和耐心下尝试了解如何在 SignalR 集线器上强制执行表单 ASP .NET 表单身份验证。

问题描述:我希望只有经过身份验证的用户才能连接 SignalR Hub 并接收/发送消息。

入侵场景:入侵者可能会捕获/访问访问客户端计算机上的临时文件的网页的 HTML 和 Javascript。因此,该入侵者可以知道设置/使用与 Hub 的连接所需的所有详细信息(方法、集线器名称等)。dfowler 提出的解决方案正在实施 IConnect

您将实现 IConnected 并在 Connect 中编写以下代码 if(!Context.User.Identity.IsAuthenticated) throw new Exception("GTFO");

因此我尝试了这样的事情

  public System.Threading.Tasks.Task Connect()
    {
        if (!Context.User.Identity.IsAuthenticated
            || !(Context.User.IsInRole("role1") || Context.User.IsInRole("role2")
            ))
            throw new Exception("User not authorized");
        return null;
    }

问题,一旦测试,是当 Connect 方法被调用时,连接已经建立,简单地抛出异常将无济于事(如果我得到了正确的事实,应该使用 Connect 在连接时向客户端发送消息,抛出异常只会产生未发送的欢迎消息)。

事实上,根据我的测试,客户端仍然可以读取所有消息(并发送它们)。

现在,我想到的方法:

  1. 完美的解决方案:拒绝或终止服务器端的连接:不知道如何在 SignalR 中执行此操作(我试图在API中找到一个方法,但没有运气)
  2. 检查用户是否是组的一部分以避免接收/发送消息给他(但这仍然容易受到洪水/DOS攻击)
  3. 向客户端发送消息以断开连接:显然在我与入侵者作战的情况下无济于事。

还有其他方法吗?在服务器端终止连接的任何方式,或者应该接受唯一真正的身份验证是主机网页之一(为所有 signalR 客户端攻击敞开大门?)

编辑

IConnect.Connect这是我使用无条件抛出异常的方法(浏览器 IE9)时客户端 - 服务器通信的顺序:

Connect抛出异常时的客户端-服务器通信

看起来 foreverFrame 失败,但 longPolling 后备正在建立并且无论如何都可以工作 - 这是在抛出块在 Javascript 中捕获的错误之后

 if (connection.state === signalR.connectionState.connecting) {
            // Connection hasn't been started yet
            throw "SignalR: Connection has not been fully initialized. 
    Use .start().done() or .start().fail() to run logic after 
    the connection has started.";
        }
4

1 回答 1

5

我们有一个问题,我们需要允许完全阻止连接。现在你必须保护每一种方法。这不是最干净的,但对于 1.0 alpha1,我们将有一些机制来执行此操作。

另一个问题是所有集线器的连接都是相同的,因此您不能拒绝特定集线器的连接。

编辑

实际上,如果您抛出它,就我的测试而言,它确实会结束连接。你看到了什么行为?

于 2012-09-01T02:43:52.990 回答