首页 文章

无法识别使用“授权”属性修饰的SignalR集线器中的用户上下文

提问于
浏览
1

服务器

MVC 5中的SignalR集线器WebApi 2,安全性:承载令牌

客户

C#类使用HttpWebRequest从WebApi控制器/令牌 endpoints 检索承载令牌

我使用herehere描述的模式将承载令牌传递给我的AuthorizeAttribute子类 .

当AuthorizeHubConnection方法中的代码执行通过调用“secureDataFormat.Unprotect(token)”传递的票证时,始终为null . 我已经确认通信两端的令牌是相同的 .

这是覆盖方法:

public override bool AuthorizeHubConnection(AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, IRequest request)
{
     var dataProtectionProvider = new DpapiDataProtectionProvider();

     var secureDataFormat = new TicketDataFormat(dataProtectionProvider.Create());
     var token = request.QueryString.Get("Bearer");
     var ticket = secureDataFormat.Unprotect(token);

     if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
     {
       // set the authenticated user principal into environment so that it can be used in the future
       request.Environment["server.User"] = new ClaimsPrincipal(ticket.Identity);
       return true;
      }

      return false;
 }

当我在没有authorize属性的情况下运行hub并在“OnConnected”覆盖中设置断点时,Context.User属性也为null .

任何帮助将不胜感激 .

丰富

2 回答

  • 2

    这是我的解决方案,在Azure和本地工作 . AngularJS,Web API和SignalR request.Environment [“server.User”]此代码在Azure上不起作用 . 首先,我创建自定义筛选器类 .

    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
        public class QueryStringBearerAuthorizeAttribute : AuthorizeAttribute
        {
            public override bool AuthorizeHubConnection(Microsoft.AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, IRequest request)
            {
                var _Authorization = request.QueryString.Get("Bearer");
            if (!string.IsNullOrEmpty(_Authorization))
            {
                var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(_Authorization);
    
                if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
                {
                    request.Environment["server.User"] = new ClaimsPrincipal(ticket.Identity);
                    return true;
                }
            }
            return false;
            }
            public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
            {
                var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
                var request=hubIncomingInvokerContext.Hub.Context.Request;
                var _Authorization = request.QueryString.Get("Bearer");
                if (!string.IsNullOrEmpty(_Authorization))
                {
                    //var token = _Authorization.Replace("Bearer ", "");
                    var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(_Authorization);
    
                    if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
                    {
                        Dictionary<string, object> _DCI = new Dictionary<string, object>();
                        _DCI.Add("server.User", new ClaimsPrincipal(ticket.Identity));
                        hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(_DCI), connectionId);
                        return true;
                    }
                }
                return false;
            }
    }
    

    然后在我从SignalR的所有连接中我放了

    connection.qs = {Bearer:localStorageService.get('authorizationData') . token};

    我的启动课程

    public void Configuration(IAppBuilder app)
            {
                app.Map("/signalr", map =>
                {
                    map.UseCors(CorsOptions.AllowAll);
                    var hubConfiguration = new HubConfiguration
                    {
                        EnableDetailedErrors = true
                    };
                    var authorizer = new QueryStringBearerAuthorizeAttribute();
                    var module = new AuthorizeModule(authorizer, authorizer);
                    GlobalHost.HubPipeline.AddModule(module);
                    map.RunSignalR(hubConfiguration);
                });
                GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule());
                ConfigureAuth(app);
            }
    

    它对我来说很完美,我不确定是否从头部发送问号字符串的令牌是一个安全问题 . 这是我的解决方案使用angularjs,asp.net web api,信号r为autenticate SignalR集线器与一个bearing令牌 .

    在您的集线器中,您可以通过这种方式访问用户变量

    public ClaimsPrincipal _User { get { return Context.Request.Environment["server.User"] as ClaimsPrincipal; } }
    
  • 1

    终于想通了,我使用了错误的库来解密令牌 . DpapiDataProtectionProvider用于自主机方案,我们托管在IIS中 . 这是功能代码 .

    public override bool AuthorizeHubConnection(Microsoft.AspNet.SignalR.Hubs.HubDescriptor    hubDescriptor, IRequest request)
     {
           var token = request.QueryString.Get("Bearer");
           var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(token);
    
            if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
            {
                 // set the authenticated user principal into environment so that it can be used in the future
                 request.Environment["server.User"] = new ClaimsPrincipal(ticket.Identity);
                 return true;
            }
    
           return false;
      }
    

相关问题