我正在尝试将IPrincipal
注入我的SignalR中心构建器。
我已经看过并尝试过“Selective IPrincipal Injection via StructureMap with SignalR”的解决方案,但不幸的是,这似乎不再适用于SignalR 2.x.
在我的调试中,我发现有时,我的集线器构造函数在堆栈中使用我的OWIN中间件调用。在这种情况下,Thread.CurrentPrincipal
是正确的值。另外(并且令人惊讶地),HttpContext.Current
也不为空。我的印象是在SignalR中它始终为空,我不是试图使用它,但我只是在观察。似乎这些调用的调用来自调用堆栈中的管道。
其他时候,调用似乎来自线程池。在这些情况下,Thread.CurrentPrincipal
是GenericPrincipal
,HttpContext.Current
为空(再次只是观察),而我似乎无法静态获取主体。但是,在集线器内部,this.Context.User
属性 具有正确的主体。
我怎样才能静态获取主体,以便将其注入中心构造函数?
答案 0 :(得分:1)
当SignalR Hubs被激活时,有时会设置HttpContext.Current
和Thread.CurrentPrincipal
,但并非总是如此。这是因为激活线程经常与ASP.NET SynchronizationContext
一起运行。在某些情况下,情况并非如此,例如,为了处理WebSocket消息或不干净的OnDisconnected事件而激活集线器。长话短说,有时这些静力学恰好存在,但你不能依赖它。
我不知道如何可靠地静态获取IPrincipal
。在你的Hub中使用Context.User
有什么问题?
答案 1 :(得分:1)
如果我理解了您正在尝试做的事情......您应该构建自己的Authorize属性,将自定义主体放入特殊的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);
}
}
然后将此属性应用于您的Hub。
如果您想了解更多相关信息,我在博文中提到了here以及更多代码示例
答案 2 :(得分:0)
我试图解决同样的问题,我找到了设置用户身份的解决方案。
我的应用程序受到saml保护,客户端应用程序发送&#34; SAML&#34;令牌作为标题的一部分。我们编写了Asp.net模块来验证令牌并准备用户身份并为响应标头添加值。
我创建了OwinStartup类,并使用下面的代码添加了我自己的请求处理器。 我已经为Longpolling测试了这段代码并且工作正常。我不确定它是如何工作的,#34; WebScoket&#34;。
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();
}