The App: Great Ways to Debug Azure Mobile Apps - Part 1

The App: Great Ways to Debug Azure Mobile Apps - Part 1

The problem with developing cloud based services, especially those involving authentication, is that at least some of the logic lives in the cloud. Attaching a debugger to that process in the cloud works, but it's a little slow and it would be faster if you could run the server and the client on your own machine and debug both ends of the pipe at once.

Well, you can.

It's based, in part, on something I found on Pluralsight, but I can't remember where. I wrote about it here. The other part is from the completely awesome guide to developing Azure Mobile Apps by Adrian Hall .

Turns out you can have your cake and eat it, too. Once again, I'm writing this up so I don't forget.

Why is this so great?

  1. You are running both client and server apps in debug mode - locally - Much faster response times result, making it quicker to edit/test/repeat. Great for those with ADD, like me.
  • You get the proper authentication done in the cloud by the Azure Mobile App Service, so all your social identity providers work and authentication and identity tokens are valid, as are identity claims. No more faking stuff.
  • All HTTP requests are exposed in a browser, which means you get to see all Json payloads, and HTTP response codes as well as some performance data. That's right, 401's, 200's, 403's, 500's, 201's and so on. I like to watch.
  • Local simulators work, too. So if you are debugging an iOS app or an Android app (or UWP) you still see all the traffic (even if you are running it on a Mac). And you don't have to make any special changes, set up IIS, mess with firewalls, etc.

It does require a little setup, so here's a list of the modifications you have to make to your stuff to make this all work. Totally worth it in my opinion.

1. Set up ngrok so external web calls can be routed to IIS Express on your machine.

Use the instructions here to do that. You'll need information from that effort before you can go on to the next part.

2. Make sure your mobile app backend is in a separate Visual Studio solution.

This just makes debugging two ends of the app at once a whole lot simpler. And don't forget to start up VS in admin mode each time or the ngrok.io stuff won't work.

3. Gather details about your Azure Mobile App from Azure

  1. Go to your Azure portal,
  • Select your mobile app from the app services list and then
  • Select Advanced Tools. This launches Kudu, and in there you can
  • Go to the Environment Variables section and
  • Copy the WEBSITE_AUTH_SIGNING_KEY (the important one) and WEBSITE_AUTH_ALLOWED_AUDIENCES.

Due to an occasional bug, you might not see the audiences variable. Don't worry about that.

4. Update your backend server WEB.CONFIG appSettings

You'll need to add the following lines to the appSettings section in your web.config:

    <add key="SigningKey" value="CB48A5***********************************6405705EA937"/>
    <add key="ValidAudience" value="https://my-app-name.azurewebsites.net/"/>
    <add key="ValidIssuer" value="https://my-app-name.azurewebsites.net/"/>
</appSettings>```

Note that the signing key is something you'll want to get rid of when you're finished testing (and probably keep out of source control systems).  Also, note the ValidAudience and ValidIssuer values.  They are just the URL of your Azure Mobile App site.  The slash on the end is important.  Don't leave that out.

**5. Update your Startup.MobileApp.cs file to use the appSettings values you just added.**

If the code below doesn't already exist, add it.  This allows your backend code to get the values you need when you are running locally.  In production, Azure values would be supplied by Azure.


    public static void ConfigureMobileApp( IAppBuilder app ) {

    ... other stuff from this method ...

    MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();
            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()
                    } );
                }
    }
**6. In the Client app, make a change to your shared/PCL code to substitute your values when you are in debug mode**

As you can see from the code below, you're saying that if you are in debug mode (running locally), then route all the app requests out to the ngrok address.  Naturally, that routes them right back to your localhost (since you followed all the steps in the link mentioned in step 1 above.

You can see how the login host is being redirected back to Azure while the app requests are sent to your debugging copy of the backend.  When you are initializing your client, use the `AppServiceUrl` and `AlternateLoginHost` in the constructor call.  In reality, I have no idea what this does if you try to run in debug mode on Azure.


    public static class Locations
        {
    #if DEBUG
        public static readonly string AppServiceUrl = "http://04fb623d.ngrok.io";
        public static readonly string AlternateLoginHost = "https://my-app-name.azurewebsites.net";
    #else
        public static readonly string AppServiceUrl = "https://my-app-name.azurewebsites.net";
        public static readonly string AlternateLoginHost = null;
    #endif
        }

**7. Using admin mode, fire up a copy of Visual Studio and run the backend site in debug mode.**

You should see the usual web page.

**8. Now fire up another copy of Visual Studio and run your app in debug mode.**

**9. Now launch a browser and point it at `localhost:4040`**

Make some requests from the client to the server and watch the browser give you all the traffic.

Pretty ridiculous.