SignalR: как обеспечить аутентификацию/завершение соединения узлов-концентраторов на стороне сервера

Этот вопрос связан с другим потоком, вы можете прочитать здесь: Проверка подлинности с помощью SignalR, где я попытался с помощью и терпением пользователя dfowler, чтобы понять, как применять формы ASP.NET Forms Authentication на концентраторе SignalR.

Описание проблемы: я хочу, чтобы только аутентифицированные пользователи могли подключать концентратор SignalR и получать/отправлять сообщения.

Сценарий вторжения: злоумышленник может потенциально захватить/получить доступ к HTML и Javascripts веб-страницы, обращаясь к временным файлам на клиентском компьютере. Таким образом, злоумышленник может знать все детали (методы, имена узлов и т.д.), Необходимые для установки/использования соединения с концентратором. Предлагаемое решение от dfowler реализует IConnect:

Вы выполнили бы IConnected и напишите следующий код в Connect if (! Context.User.Identity.IsAuthenticated), чтобы добавить новое исключение ( "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):

client-server communication when Connect throws exception

Похоже, что 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.";
        }

Ответ 1

У нас есть проблема, когда нам нужно полностью блокировать соединение. Прямо сейчас вам придется защищать каждый метод. Это не самый чистый, но для 1.0 alpha1 у нас будет некоторый механизм для этого.

Еще одна проблема заключается в том, что это одно и то же соединение для всех концентраторов, поэтому вы не можете отклонить соединение для определенного концентратора.

ИЗМЕНИТЬ

На самом деле, если вы его выбросите, это прекратит соединение до моего тестирования. Какое поведение вы видите?