Подключение к концентратору SignalR из консоли с помощью ClaimsPrincial

У меня есть очень простой концентратор SignalR, который запущен и работает на моем сервере. Используя пример от Micorsoft, я создал хранилище в памяти для сопоставления пользователей из ClaimsPrincipal со словарем в памяти. Вот код:

 public class NotificationHub : Hub
{
    private readonly static ConnectionMapping<string> _connections = new ConnectionMapping<string>();
    
    public void SendNotification(string who, NotificationData message)
    {
        string name = Context.User.Identity.Name;
        foreach(var connectionId in _connections.GetConnections(who))
        {
            Clients.Client(connectionId).SendAsync("Notification", message);
        }
    }

    public override Task OnConnectedAsync()
    {
        
        string name = Context.UserIdentifier;
        _connections.Add(name, Context.ConnectionId);
        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(System.Exception exception)
    {
        string name = Context.User.Identity.Name;
        _connections.Remove(name, Context.ConnectionId);
        return base.OnDisconnectedAsync(exception);
    }
}

Я хочу протестировать это с помощью консольного приложения, но не могу понять, как создать ClaimsPrincipal в консольном приложении .net core. Вот код моего консольного приложения:

class Program
{
    static async Task Main(string[] args)
    {

        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
        Console.WriteLine("Press a key to start listening");
        Console.ReadKey();

        Console.WriteLine("Client Listening!");
        var connection = new HubConnectionBuilder()
           .WithUrl("https://localhost:44375/Notify")
           .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
          //.ConfigureLogging(logging =>
          //{
          //    logging.AddConsole();
          //    logging.SetMinimumLevel(LogLevel.Debug);
          //})
           .Build();




        connection.On<NotificationData>("Notification", (notificationData) =>
            Console.WriteLine($"Somebody connected: {notificationData.ClientId}"));

        connection.StartAsync().GetAwaiter().GetResult();
      
        while(Console.ReadKey().Key == ConsoleKey.S)
        {
            var msg = new NotificationData { ClientId = Guid.NewGuid().ToString(), Notifications = null };
            await connection.SendAsync("SendNotification", msg);
            
        }

        
        Console.WriteLine("Listening. Press a key to quit");
        Console.ReadKey();

        connection.Reconnecting += error =>
        {
            Console.WriteLine("Reconnecting...");
            return Task.CompletedTask;
        };
    }
}

Я пытался использовать WindowsPrincipal, но не смог отправить имя. Очевидно, SignalR должен иметь принципала утверждений. Как вы отправляете претензию принципалу из консольного приложения?


person john    schedule 12.12.2020    source источник


Ответы (1)


Мне удалось создать объект QueryBuilder, чтобы перехватить идентификатор пользователя из опубликованного документа JSON и создать строку URI с добавленными элементами QueryBuilder. Затем в методе OnConnectedAsync концентратора я использовал метод Context.GetHttpContext, чтобы извлечь пользователя из строки запроса и добавить его в группу. Затем я сопоставляю его со словарем в памяти, чтобы сопоставить userId с Context.ConnectionId.

person john    schedule 17.12.2020