2013-04-05 2 views
6

Я ищу некоторые рекомендации о том, как реализовать защиту авторизации для SignalR на задней службе, работающей в среде с самообслуживанием (не-IIS), которая называется из веб-приложения. Бэкэнд-приложение - это в основном монитор, который возвращает события SignalR обратно клиенту на основе HTML. Все это прекрасно работает (на самом деле это потрясающе хорошо).Реализация авторизации на самообслуживаемом сервере SignalR, доступ к которому осуществляется через Интернет

Однако нам необходимо ограничить доступ к серверу для аутентифицированных пользователей с веб-сайта. Таким образом, в основном, если пользователь аутентифицирован на веб-сайте, нам нужно как-то подобрать критические (достаточно имя пользователя) и состояние проверки в бэкэнд-приложении, чтобы решить, разрешать ли подключение, чтобы избежать несанкционированного доступа.

Может ли кто-нибудь указать на некоторые стратегии или шаблоны на то, как выполнить эту авторизацию?

+0

Я реализовал защиту на основе токенов, передав сгенерированный токен пользователя с каждым сигнальным запросом через строку запроса (то есть $ .connection.hub.qs). Клиент получает ключ, который перекрестно ссылается на пользователя, а на сервере я беру токен, а затем загружаю пользователя из перекрестного ref. Он работает, но он довольно уродлив, и я не могу понять, как чисто обеспечить безопасность, не вызывая метод ValidateToken(), который вызывает ошибку. –

+0

Любое обновление по этому вопросу? Вы нашли лучший способ сделать это еще? Я сталкиваюсь с такой же ситуацией. – BowserKingKoopa

ответ

2

SignalR не предоставляет никаких дополнительных функций для аутентификации. Вместо этого он предназначен для работы с механизмом аутентификации вашего приложения.

концентраторы

Вы должны сделать проверку подлинности, как обычно, а затем использовать атрибут Авторизовать предоставленный SignalR для обеспечения результатов аутентификации на концентраторы.

Атрибут Authorize может быть применен ко всему концентратору или конкретным методам в концентраторе. Некоторые примеры:

  • [Авторизоваться] - только идентифицированные пользователи
  • [авторизовать (Roles = "Администратор, менеджер")] - только пользователям, прошедшим проверку в указанных ролей .NET
  • [авторизовать (Пользователи = " user1, user2")] - только пользователям, прошедшим проверку с указанными именами пользователей

Вы можете также требовать все концентраторы для требуют проверки подлинности, добавив следующий метод в методе Application_Start:

GlobalHost.HubPipeline.RequireAuthentication();

Стойкие соединения

Вы можете использовать объект пользователя в запросе, чтобы увидеть, если проверка подлинности пользователя:

request.User.IsAuthenticated

+2

Я не использую ASP.NET для размещения этого сервиса SignalR, поэтому я не думаю, что это работает, потому что нет безопасности ASP.NET или Identity для проверки. Получаю, что SignalR не обеспечивает встроенную аутентификацию, что хорошо. Я прошу идеи о том, как передать контекст безопасности в приложениях, а затем, как в целом обрабатывать аутентификацию, не переполняя вызовы для проверки безопасности в каждом методе хаба. –

2

Я схожие проблемы здесь, как в моем веб-приложении, я использую простую систему аутентификации cookie, которая использует подход стиля AoP для проверки любые контроллеры с атрибутом, затем получит текущий контекст (будь то из статического HttpContext.Current или из целевого объекта вызова в зависимости от типа перехватчика), а затем проверьте, существует ли файл cookie, он содержит правильные данные, а затем, наконец, проверьте токен с db или кешем и т. д.

В любом случае этот подход также может использоваться для Signalr, хотя его бит более длинный, и вы используете инъекцию зависимости.Вы бы в основном обернули вызовы концентратора с требуемым атрибутом, а затем настроили конфигурацию DI/IoC для перехвата этих вызовов, затем либо получите экземпляр хаба в своем перехватчике, либо получите cookie (или ваш собственный механизм аутентификации) из запроса, проверьте все это действует или нет, а если нет, то выкиньте new HttpException("403", "Not authenticated");, который должен отбросить пользователя и вернуться назад, прежде чем он даже ударит по вашему хаб-методу, таким образом вы можете поместить логику в одном месте (ваш перехватчик или класс перехватчик потребляет), то просто оберните любой метод, который должен использовать эту аутентификацию, используя ваш атрибут.

Я использую Ninject и расширение перехвата, но большинство крупных DI каркасов в эти дни имеют некоторую форму IoC плагин/расширения, такие как Autofac, Виндзор, весной и т.д.

Если вы не были счастливы идти вниз маршрут введения DI и/или AOP в ваш текущий проект, то, возможно, вы могли бы просто создать пользовательский экземпляр хаба, который содержит вашу логику аутентификации, а затем просто использовать это в ваших концентраторах, так что вы все равно будете вручную вызывать некоторую логику аутентификации изнутри каждого хаб метод, который вы хотите защитить, но его меньше кода, так что-то вроде:

public class AuthorisableHub : Hub 
{ 
    private ISomeAuthenticationToken GetSomeAuthenticationTokenFromRequest(Request request) // probably a SignalR specific request object 
    { 
     // Get your token from the querystring or cookie etc 
    } 

    private bool IsAuthenticationTokenValid(ISomeAuthenticationToken token) 
    { 
     // Perform some validation, be it simple or db based and return result 
    } 

    protected void PerformUserAuthentication() 
    { 
     var token = GetSomeAuthenticationTokenFromRequest(Context.Request); 
     var isRequestValid = IsAuthenticationTokenValid(token); 

     if(!isRequestValid) 
     { throw new HttpException(403, "<Some forbidden message here>"); } 
    } 
} 

public class MyFancyPantsHub : AuthorisableHub 
{ 
    public void TellAllClientsSomethingSecret(ISecret secret) 
    { 
     PerformUserAuthentication(); 

     // Do stuff with the secret as it should have bombed the user out 
     // before it reaches here if working correctly 
    } 
} 

Это не идеально, но будет работать (я думаю), также я уверен, что когда-то я читал, что Hubs снова создаются для каждого запроса, и если это действительно так, вы можете просто поместить эту логику в свой конструктор, если хотите применять аутентификацию для каждого действия внутри концентратора.

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

Смежные вопросы