简体   繁体   English

SignalR:如何强制认证/终止集线器连接服务器端

[英]SignalR: how to enforce authentication/terminate hub connections server side

This question is related to another thread, you can read here: Forms authentication with SignalR where I tried with the help and patience of the user dfowler to understand how enforce forms ASP .NET Forms Authentication on a SignalR Hub. 这个问题与另一个线程有关,您可以在这里阅读:使用SignalR进行表单身份验证 ,我在用户dfowler的帮助和耐心下尝试了解如何在SignalR Hub上强制执行A​​SP .NET Forms身份验证。

Description of the problem: I want that only authenticated users can connect the SignalR Hub and receive/send messages. 问题描述:我希望只有经过身份验证的用户才能连接SignalR Hub并接收/发送消息。

Intrusion scenario: the intruder can potentially capture/access the HTML and Javascripts of the web page accessing the temporary files on a client computer. 入侵场景:入侵者可以捕获/访问访问客户端计算机上临时文件的网页的HTML和Javascripts。 This intruder can therefore know all the details (methods, hub names etc) required to set up/use a connection to the Hub. 因此,该入侵者可以知道建立/使用与Hub的连接所需的所有细节(方法,集线器名称等)。 A proposed solution from dfowler is implementing IConnect : dfowler提出的解决方案是实现IConnect

You would implement IConnected and write the following code in Connect if(!Context.User.Identity.IsAuthenticated) throw new Exception("GTFO"); 您将实现IConnected并在Connect if(!Context.User.Identity.IsAuthenticated)中抛出以下代码抛出新的异常(“GTFO”);

Therefore I tried with something like this 所以我试着用这样的东西

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

The problem, once tested, is that when the Connect method is being called, the connection has been already established and plain throwing the exception will not help (if I got if properly infact Connect should be used to send a message to the client at connection, throwing an exception will just yield in a welcome message not sent). 一旦经过测试,问题在于,当调用Connect方法时,连接已经建立并且普通抛出异常将无济于事(如果我得到了正确的实际连接应该用于在连接时向客户端发送消息)抛出异常只会产生一条未发送的欢迎消息 )。

In facts, from my tests, the clients can still read all the messages (and also send them). 事实上,从我的测试中,客户端仍然可以读取所有消息(并发送它们)。

Now, approaches which come to my mind: 现在,我想到的方法:

  1. Perfect solution: reject or terminate the connection on server side: no clue how to do this in SignalR (I tried to find a method in the API but no luck) 完美的解决方案:拒绝或终止服务器端的连接: 不知道如何在SignalR中执行此操作 (我试图在API中找到一个方法,但没有运气)
  2. check if the user is part of a group to avoid receiving/sending messages to him (but this is still prone to flooding/DOS attacks) 检查用户是否属于某个组以避免接收/发送消息给他(但这仍然容易发生洪水/ DOS攻击)
  3. Sending a message to the client to disconnect: obviously does not help in case I am fighting an intruder. 向客户端发送消息以断开连接:如果我正在与入侵者作战,显然无济于事。

Any other approach? 还有其他方法吗? Any way to terminate the connection on server side or should be accepted that the only real authentication is the one of the host webpage (leaving open the door to all the signalR client attacks?) 任何方式终止服务器端的连接或应该接受唯一真正的身份验证是主机网页之一(打开所有signalR客户端攻击的大门?)

EDIT 编辑

Here is the sequence of client - server communication when I use the IConnect.Connect method throwing unconditionally an exception (browser IE9): 以下是我使用IConnect.Connect方法无条件抛出异常(浏览器IE9)时客户端 - 服务器通信的顺序:

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

It looks like the foreverFrame fails but the longPolling fallback is being established and works anyway - this after throwing the error captured in the Javascript by the block 它看起来像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.";
        }

We have an issue where we need to allow blocking the connection altogether. 我们有一个问题,我们需要允许完全阻止连接。 Right now you'll have to guard each method. 现在你必须保护每种方法。 It's not the cleanest but for 1.0 alpha1 we'll have some mechanism for doing this. 这不是最干净的,但对于1.0 alpha1,我们将有一些机制来做到这一点。

One additional problem is that it's the same connection for all hubs so you can't reject a connection for a specific hub. 另一个问题是,所有集线器的连接都是相同的,因此您无法拒绝特定集线器的连接。

EDIT 编辑

Actually if you throw it does end the connection as far as my testing goes. 实际上,如果你抛出它确实结束了我的测试的连接。 What behavior are you seeing? 你看到了什么行为?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM