tofutim
tofutim

Reputation: 23374

Enabling Authentication with SIgnalR against Azure Mobile Services when debugging on localhost

this is similar to Enabling Authentication with SIgnalR against Azure Mobile Services and a Javascript client but with a twist. I have a Zumo-authenticated app that has SignalR that I would like to locally debug. For the client,

public App()
{
#if DEBUG            
  var client = new MobileServiceClient(debugUrl);
  client.AlternateLoginHost = new Uri(releaseUrl);
#else
  var client = new MobileServiceClient(mobileAppReleaseUrl);
#endif
  var hub = new HubConnection(client.MobileAppUri.AbsoluteUri);
..
}

to authenticate SignalR, I am using

conn.Headers["x-zumo-auth"] = _appService.CurrentUser.MobileServiceAuthenticationToken;

and server-side I use

public class ZumoUserIdProvider : IUserIdProvider
{
    public string GetUserId(IRequest request)
    {
        if (request == null)
        {
            throw new ArgumentNullException("request");
        }

        if (request.User != null && request.User.Identity != null)
        {
            var identity = (ClaimsIdentity)request.User.Identity;
            var identifier = identity.FindFirst(ClaimTypes.NameIdentifier);
            if (identifier != null)
            {
                return identifier.Value;
            }
        }

        return null;
    }
}

along with

GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new ZumoUserIdProvider());

Amazingly, this actually works when published to Azure, though I'm a little bit worried about Web Sockets (maybe I need to stuff the token into the query string). The problem now is that when debugging in localhost, although I am able to authenticate (social login), I always get unauthenticated when I try to use SignalR on the localhost side. How can I make it work?

Update. i think there used to be SignalRExtensionConfig.Initialize(); although I don't see it in the current version of Azure Mobile Services. This is found in WindowsAzure.MobileServices.Backend.SignalR but it has really exact dependencies that do not look easy to fulfill, e.g., AspNet.Cors = 5.2.2, I have 5.2.3.

Update2. Apparently there is https://msdn.microsoft.com/en-us/library/azure/mt587593.aspx

SignalRExtensionConfig Class

The SignalRExtensionConfig class provides configuration specific to SignalR. Namespace: Microsoft.Azure.Mobile.Server.Config Assembly: Microsoft.Azure.Mobile.Server.SignalR (in Microsoft.Azure.Mobile.Server.SignalR.dll)

but I do not see this in nuget. I'm just using the regular AspNet SignalR library. My Setup looks like

   public static void ConfigureMobileApp(IAppBuilder app)
    {            
        HttpConfiguration config = new HttpConfiguration();

        new MobileAppConfiguration()
            .UseDefaultConfiguration()
            .ApplyTo(config);

        // Use Entity Framework Code First to create database tables based on your DbContext
        //            Database.SetInitializer(new MobileServiceInitializer());
        var migrator = new DbMigrator(new Migrations.Configuration());
        migrator.Update();

        MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();

        // http://blogs.perficient.com/microsoft/2016/05/how-to-add-custom-claims-to-azure-mobile-app-authentication/
        if (string.IsNullOrEmpty(settings.HostName))
        {
            app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
            {
                // This middleware is intended to be used locally for debugging. By default, HostName will
                // only have a value when running in an App Service application.
                SigningKey = ConfigurationManager.AppSettings["SigningKey"],
                ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] },
                ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] },
                TokenHandler = config.GetAppServiceTokenHandler()
            });
        }

        app.Map("/signalr", map =>
        {
            map.UseCors(CorsOptions.AllowAll);
            //map.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
            //{
            //    Provider = new ZumoOAuthBearerProvider()
            //});
            var hubConfig = new HubConfiguration
            {
                Resolver = GlobalHost.DependencyResolver
            };
            map.RunSignalR(hubConfig);
        });

        app.UseWebApi(config);

    }

Upvotes: 1

Views: 421

Answers (2)

Adrian Hall
Adrian Hall

Reputation: 8035

You are following a tutorial for Azure Mobile Services, yet using Azure Mobile Apps. The two are not compatible.

Explicitly, we have not included SignalR in the latest SDKs - this is something you are going to have to implement yourself. When you have Authentication set up properly, a simple [Authorize] tag on any controller will ensure the user is authenticated.

The SignalR setup is orthogonal to Azure Mobile Apps now.

Upvotes: 0

George Chondrompilas
George Chondrompilas

Reputation: 3247

As I can see you are using Azure Mobile App Service.

I would say that the problem is that you can't social log in correctly when running the app service locally. The callback URIs you specified on the social provider when enabling the social authentication, are set to your mobile app service URI instead of localhost, that's why you are not getting the authentication headers as x-zumo-auth back.

A workaround would be to enable Remote Debugging, deploy a debug build to your Mobile App Service and remotely debug it.

See more here: Troubleshoot a web app in Azure App Service using Visual Studio

Upvotes: 1

Related Questions