如何从 SignalR Hub 获取 Azure Entra 用户 ID?

问题描述 投票:0回答:1

我正在开发一种“通知观察者”服务,该服务使用 SignalR 从 Angular 应用程序收集连接的用户(该应用程序使用 Azure Entra 作为身份验证)。此“观察者”服务将检测(通过服务总线或对集线器的调用)其他应用程序已为特定的用户 ID 组(Entra 用户 ID 列表,即 GUID)创建了新通知,然后如果这些特定用户连接到 Hub 实例,它应该能够仅向这些特定用户发送此通知。 enter image description here

问题是,我真的不知道这是否可行,我知道您可以将 SignalR 配置为需要使用 Azure Entra 进行身份验证,但我正在努力查找有关 SignalR 是否可以通过 Azure Entra 区分这些连接用户的信息ID,类似:

foreach(var entraUserId in notification.Users)
  await this.hubContext.Client(entraUserId).SendAsync(message);

或者,如果我必须做一些特别的事情,我知道 .Client() 需要一个 connectionId 映射到特定连接,但我感觉有一个我不知道的链接能够将 Entra 用户 ID 映射到 connectionId。

azure signalr signalr-hub azure-signalr azure-entra-id
1个回答
0
投票

要通过用户 ID(与 Azure AD objectId 相关)获取连接,您必须自己创建和维护用户和连接之间的映射。您可以通过向 OnConnected 和 OnDisconnected 事件添加替代来实现此目的,如下所示:

public class ChatHub : Hub
{
    private readonly static Dictionary<string, string> _connections = new Dictionary<string, string>();

    public override Task OnConnectedAsync()
    {
        var userId = Context.UserIdentifier; // This should be objectId GUID
        var connectionId = Context.ConnectionId;

        // Add the connection ID and user ID to the mapping
        lock (_connections)
        {
            if (!_connections.ContainsKey(userId))
            {
                _connections[userId] = connectionId;
            }
            else
            {
                _connections[userId] = connectionId;
            }
        }

        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        var userId = Context.UserIdentifier;

        // Remove the connection ID and user ID from the mapping
        lock (_connections)
        {
            if (_connections.ContainsKey(userId))
            {
                _connections.Remove(userId);
            }
        }

        return base.OnDisconnectedAsync(exception);
    }

    public async Task SendNotificationToUser(string userId, string message)
    {
        // Retrieve the connection ID for the specified user
        if (_connections.TryGetValue(userId, out var connectionId))
        {
            // Send the notification to the specified user's connection
            await Clients.Client(connectionId).SendAsync("ReceiveNotification", message);
        }
        else
        {
            // Code to handle instances where user is not found.
            // Log or ignore, I guess.
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.