我有一个单独的IIS安装的Web应用程序(这不会改变),但有一个动态的子域集合。每个子域都有自己的用户帐户。
我遇到的问题是,当我在其上运行signalR时,它会将所有子域视为同一个域,因此恰好具有相同用户名的用户将获得彼此的消息。
这导致我在域帐户之间出现安全违规问题。
到目前为止,我最好的猜测解决方案有不同程度的风险和问题。
要查看此失败,只需在ASP.NET/SignalR上获取简单的聊天演示,然后在本地计算机上的两个不同浏览器(FF和IE进行核心测试)下运行它,并调用http:\ localhost另一个叫http:\ yourcomputername。您需要IIS而不是IIS Express才能进行正确的测试。
答案 0 :(得分:1)
我的2美分:构建自己的IUserIdProvider
实现,从那里应该很容易检查每个请求并在多个域中生成一个唯一的用户ID,这样你就会返回,这样SignalR会知道向谁发送正确关联每个请求。它是一种简单而非侵入性的解决方案。您可以查看here了解更多详情。
答案 1 :(得分:1)
我知道这有点晚了,不过我也遇到过这个问题而且我已经使用群组解决了它,但是我这样做是为了自己实现IHub然后设置Clients
在我自己的IHubCallerConnectionContext<dynamic>
实现中调用值,然后使用键来隔离使用已有方法进行的所有调用。以下是该类的示例:
internal class ClientsDatabaseIsolator : IHubCallerConnectionContext<object>
{
private readonly string _database;
private readonly IHubCallerConnectionContext<dynamic> _clients;
public ClientsDatabaseIsolator(string database, IHubCallerConnectionContext<dynamic> clients)
{
if (database == null) throw new ArgumentNullException(nameof(database));
this._database = database;
this._clients = clients;
}
private string PrefixDatabase(string group)
{
return string.Concat(_database, ".", group);
}
public dynamic AllExcept(params string[] excludeConnectionIds)
{
return _clients.Group(_database, excludeConnectionIds);
}
public dynamic Client(string connectionId)
{
return _clients.Client(connectionId);
}
public dynamic Clients(IList<string> connectionIds)
{
return _clients.Clients(connectionIds);
}
public dynamic Group(string groupName, params string[] excludeConnectionIds)
{
return _clients.Group(PrefixDatabase(groupName), excludeConnectionIds);
}
public dynamic Groups(IList<string> groupNames, params string[] excludeConnectionIds)
{
return _clients.Groups(groupNames.Select(PrefixDatabase).ToList(), excludeConnectionIds);
}
public dynamic User(string userId)
{
return _clients.User(userId);
}
public dynamic Users(IList<string> userIds)
{
return _clients.Users(userIds);
}
public dynamic All
{
get { return _clients.Group(_database); }
}
public dynamic OthersInGroup(string groupName)
{
return _clients.OthersInGroup(PrefixDatabase(groupName));
}
public dynamic OthersInGroups(IList<string> groupNames)
{
return _clients.OthersInGroups(groupNames.Select(PrefixDatabase).ToList());
}
public dynamic Caller
{
get { return _clients.Caller; }
}
public dynamic CallerState
{
get { return _clients.CallerState; }
}
public dynamic Others
{
get { return _clients.OthersInGroup(_database); }
}
}
然后在OnConnected
我将连接添加到_database
组
现在在我的集线器中,当我致电Clients.All.Send("message")
时,它实际上只是在创建ClientsDatabaseIsolator
时向指定的群组发送消息,就像打电话给Clients.Group(database).Send("message")
一样。我必须考虑一下。我不确定这是否是最佳解决方案,但它对我们有用。