簡體   English   中英

如何防止從一個 JWT 聲明到一個集線器的多個連接 [SignalR,C#]

[英]How to prevent multiple connection from one JWT claim to one hub [SignalR, C#]

假設我們的應用程序接受 SignalR Hub 上的 JWT 承載授權。

既然我們禁止匿名連接,那么我們也有可以限制於此的數據,對吧? 任務是同時阻止從該令牌到 Hub 的多個連接。

我想出了創建用戶列表並通過 OnConnected / OnDisconnected 添加/刪除的想法,然后拒絕請求,這是個好主意還是有更好的選擇?

如果有人對我的實現感興趣,那就是(我認為它可以更好):

集線器.cs:

    private static readonly ConnectionMapping Connections = new();
    
    public async Task JoinGroup(string group)
    {
        string username = Context.User.Identity.Name;

        Connections.Add(group, username);
        
        await Groups.AddToGroupAsync(Context.ConnectionId, group);
        await Clients.Group(group).SendAsync("UserConnected", Connections.GetConnections(group));
    }

    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        string username = Context.User.Identity.Name;
        string group = Connections.GetKey(username);
        
        Connections.Remove(group, username);
        
        await Clients.Group(group).SendAsync("UserConnected", Connections.GetConnections(group));
        
        await base.OnDisconnectedAsync(exception);
    }

連接映射.cs:

public class ConnectionMapping
{
    private readonly Dictionary<string, List<string>> _groups = new();

    public void Add(string key, string connectionId)
    {
        List<string> connections;
        
        if (!_groups.TryGetValue(key, out connections))
        {
            connections = new List<string>();
            _groups.Add(key, connections);
        }

        connections.Add(connectionId);
    }

    public void Remove(string key, string connectionId)
    {
        List<string> connections;
        
        if (!_groups.TryGetValue(key, out connections))
            return;

        connections.Remove(connectionId);

        if (connections.Count == 0)
            _groups.Remove(key);
    }
    
    public IEnumerable<string> GetConnections(string key)
    {
        List<string> connections;
        
        if (_groups.TryGetValue(key, out connections))
            return connections.Distinct();

        return Enumerable.Empty<string>();
    }

    public string GetKey(string connectionId)
    {
        string key = _groups.FirstOrDefault(x => x.Value.Contains(connectionId)).Key;

        if (!key.IsNullOrEmpty()) 
            return key;
        
        return string.Empty;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM