5

我正在尝试注入IPrincipal我的 SignalR 集线器构造函数。我已经看到并尝试了“ Selective IPrincipal Injection via StructureMap with SignalR ”中的解决方案,但不幸的是,这似乎不再适用于 SignalR 2.x。

在我的调试中,我发现有时,我的集线器构造函数是在堆栈中使用我的 OWIN 中间件调用的。在这种情况下,Thread.CurrentPrincipal是正确的值。此外(并且令人惊讶地),HttpContext.Current也不是空的。我的印象是这在 SignalR 中总是空的,我没有尝试使用它,但我只是在观察。这些有效的调用似乎来自调用堆栈中的管道。

其他时候,调用似乎来自线程池。在那些情况下,Thread.CurrentPrincipalis a GenericPrincipal, HttpContext.Currentis null (再次只是观察),我似乎无法静态地了解主体。但是,在枢纽内部,该this.Context.User物业确实有正确的委托人。

我还能如何静态获取主体,以便可以将其注入集线器构造函数?

4

3 回答 3

2

当 SignalR Hub 被激活时,预计HttpContext.Current并且Thread.CurrentPrincipal有时会设置,但并非总是如此。这是因为激活线程通常使用 ASP.NET 的SynchronizationContext. 在某些情况下,情况并非如此,例如当激活 Hub 以处理 WebSocket 消息或不干净的 OnDisconnected 事件时。长话短说,有时这些静态因素恰好存在,但你不能依赖它。

我不知道有什么方法可以静态地获得IPrincipal可靠的。Context.User在 Hub 内使用有什么问题?

于 2014-12-15T23:15:48.420 回答
1

如果我正确理解了您要执行的操作...您应该构建自己的 Authorize 属性,这会将自定义主体放入特殊的 Owin var 中,然后可以在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);
    }
}

然后将此属性应用于您的集线器。

如果您想了解更多信息,我在这里写了更多代码示例的博客

于 2017-09-09T11:47:33.913 回答
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();
    }
于 2015-08-13T11:29:41.643 回答