2014-12-15 6 views
4

Я пытаюсь ввести IPrincipal в мои конструкторы концентратора SignalR. Я уже видел и пробовал решение от «Selective IPrincipal Injection via StructureMap with SignalR», но, к сожалению, это больше не работает для SignalR 2.x.Inject IPrincipal с SignalR

В моей отладке я обнаружил, что иногда, мой конструктор хаба вызывается с моим промежуточным программным обеспечением OWIN в стеке. Если это так, Thread.CurrentPrincipal - правильное значение. Дополнительно (и удивительно) HttpContext.Current также не является нулевым. Я был под впечатлением, что это всегда было нулевым в SignalR, и я не пытаюсь его использовать, но я просто наблюдаю. Похоже, что эти вызовы работают из конвейера в стеке вызовов.

Другие вызовы, похоже, происходят из пула потоков. В этих случаях Thread.CurrentPrincipal является GenericPrincipal, HttpContext.Current является нулевым (опять-таки просто наблюдением), и я не могу, по-видимому, получить стратегическое значение. Тем не менее, внутри хаба, this.Context.User имущество делает имеют право принципала.

Как еще я могу получить главный статически, чтобы я мог ввести его в конструктор хаба?

+0

Чтобы решить эту проблему, я сделал WebAPI: пользователи могут присоединиться к группам или отправлять сообщения с помощью моего API. В этом API я могу проверить личность/роли. – Guillaume

+0

@Guillaume Как это решить SignalR? –

+0

Это не решит вашу проблему, поэтому я не опубликовал ответ. Это wrokaround, чтобы получить IPrincipal для всех входящих действий от пользователей.Контроллер действует как прокси-сервер между клиентом и концентратором. Наверное, не очень хорошо для реального времени (игры, ...). – Guillaume

ответ

1

Если я правильно понял, что вы пытаетесь сделать ... Вы должны создать свой собственный атрибут Авторизовать, что поставит пользовательский принципал в специальный Owin вар, то он будет доступен в Context.User Внутри хаб.

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) 
    { 
     //put our custom user-principal into a magic "server.User" Owin variable 
     request.Environment["server.User"] = new MyCustomPrincipal(); //<!-THIS! 

     return base.AuthorizeHubConnection(hubDescriptor, request); 
    } 
} 

А затем примените этот атрибут к своему концентратору.

Если вы хотите получить больше информации об этом, я писал о этом here с большим количеством примеров кода

1

Ожидается, что и Thread.CurrentPrincipal будут установлены, когда сигнальные концентраторы активируются, но не всегда. Это связано с тем, что активирующий поток часто работает с ASP.NET SynchronizationContext. Бывают ситуации, когда это не так, например, когда концентратор активирован для обработки сообщения WebSocket или нечистого события OnDisconnected. Короче говоря, иногда эта статика оказывается там, но на нее нельзя положиться.

Я не знаю, как статически получить IPrincipal надежно. Что случилось с использованием Context.User внутри вашего концентратора?

+0

'Context.User' полагается на более тесную связь с инфраструктурой хабов SignalR, что уменьшает возможность для меня (например) совместного использования кода между SignalR и Web API без функций обертки. –

0

Я пытался решить ту же проблему, и я нашел решение установить личность пользователя.

Мое приложение защищено saml, а клиентское приложение отправляет токен «SAML» как часть заголовка. Мы написали модуль Asp.net, чтобы проверить токен и подготовить идентификатор пользователя и добавить значение в заголовки ответов.

Я создал класс OwinStartup, и я добавил свой собственный процессор запросов, используя приведенный ниже код. Я проверил этот кусок кода для Longpolling и отлично работал. Я не уверен, как это работает в «WebScoket».

public void Configuration(IAppBuilder app) 
    { 
     // Any connection or hub wire up and configuration should go here   
     try 
     { 
      app.Use(SetMyPrincipalObject); 
     } 
    } 

    private Task SetMyPrincipalObject(IOwinContext arg1, Func<Task> arg2) 
    { 
     //var p = "Process response";//Process Response Header here and //create identity 
     //arg1.Request.User = p; 
     //return arg2.Invoke(); 
    } 
+0

Это вообще не отвечает на вопрос. –

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