如何使用Azure移动应用程序身份验证授权SignalR集线器



我的移动应用程序通过azure使用Facebook Auth。对于带有[MobileApiController]标志的ApiControllers,auth运行良好。

我似乎找不到如何使SignalR Hub授权——authorize属性阻止用户访问。我发现的所有文章似乎都很旧,都使用了不推荐使用的Azure移动服务,这是不同的,也不兼容。

我已经将SignalR客户端配置为使用x-zumo-auth头集连接长轮询。

我最终制作了一个自定义SignalR身份验证属性。下面的代码供其他感兴趣的人使用。

  public class HubAuthorizeAttribute : AuthorizeAttribute
  {
    public HubAuthorizeAttribute()
    {
    }
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
    {
        var owinContext = request.GetHttpContext().GetOwinContext();
        ClaimsPrincipal claimsPrincipalFromToken;
        var options = Startup.AuthenticationOptions;
        string tokenFromHeader = request.Headers[AppServiceAuthenticationHandler.AuthenticationHeaderName];
        if (!string.IsNullOrEmpty(tokenFromHeader))
        {
            bool claimsAreValid = options.TokenHandler.TryValidateLoginToken(tokenFromHeader, options.SigningKey, options.ValidAudiences, options.ValidIssuers, out claimsPrincipalFromToken);
            if (claimsAreValid)
            {
                var identity = claimsPrincipalFromToken.Identity as ClaimsIdentity;
                request.Environment["server.User"] = new ClaimsPrincipal(identity);
                return true;
            }
        }
        return false;
    }
    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    {
        var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
        // check the authenticated user principal from environment
        var environment = hubIncomingInvokerContext.Hub.Context.Request.Environment;
        var principal = environment["server.User"] as ClaimsPrincipal;
        if (principal != null && principal.Identity != null && principal.Identity.IsAuthenticated)
        {
            // create a new HubCallerContext instance with the principal generated from token
            // and replace the current context so that in hubs we can retrieve current user identity
            hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(environment), connectionId);
            return true;
        }
        else
        {
            return false;
        }
    }
}

最新更新