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

How can I authorize a SignalR Hub using Azure Mobile Apps Authentication

我的移动应用程序通过 Azure 使用 Facebook Auth。对于带有 [MobileApiController] 标志的 ApiControllers,auth 工作正常。

我似乎找不到如何让我的 SignalR Hub 授权 - 授权属性阻止用户访问。我发现的所有文章似乎都过时了,并且使用的是已弃用的 Azure 移动服务,这是不同且不兼容的。

我已将我的 SignalR 客户端配置为 long-polling 与 x-zumo-auth header 集连接。

我最终创建了自定义 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;
        }
    }
}