Reputation: 611
I have my mobile app using Facebook Auth through azure. The auth works fine for the ApiControllers with the [MobileApiController]
flag.
I can't seem to find how to make my SignalR Hub authorize - the Authorize attribute blocks access from users. All the articles I have found seem to be old and using the deprecated Azure Mobile Services which is different and not compatible.
I have configured my SignalR client to connect as long-polling with the x-zumo-auth header set.
Upvotes: 0
Views: 469
Reputation: 611
I ended up making a custom SignalR authentication attribute. Code below for anyone else interested.
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;
}
}
}
Upvotes: 1