这个问题与另一个线程有关,您可以在此处阅读:使用 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 在连接时向客户端发送消息,抛出异常只会产生未发送的欢迎消息)。
事实上,根据我的测试,客户端仍然可以读取所有消息(并发送它们)。
现在,我想到的方法:
- 完美的解决方案:拒绝或终止服务器端的连接:不知道如何在 SignalR 中执行此操作(我试图在API中找到一个方法,但没有运气)
- 检查用户是否是组的一部分以避免接收/发送消息给他(但这仍然容易受到洪水/DOS攻击)
- 向客户端发送消息以断开连接:显然在我与入侵者作战的情况下无济于事。
还有其他方法吗?在服务器端终止连接的任何方式,或者应该接受唯一真正的身份验证是主机网页之一(为所有 signalR 客户端攻击敞开大门?)
编辑
IConnect.Connect
这是我使用无条件抛出异常的方法(浏览器 IE9)时客户端 - 服务器通信的顺序:
看起来 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.";
}