Azure Hybrid Connections – Connect to Protected Resources

Azure Hybrid Connections make it easy to create secure connections between protected resources and external devices: mobile phones, tablets, laptops, you name it.  The architecture looks something like this:

HybridConn

To demonstrate this, let’s reuse existing blogs and tutorials to get to a good starting point.  Using Authenticate your app with Active Directory Authentication Library Single Sign-On, followed by links you’ll find there (either Get Started With Mobile Services or Get Started with Data) you should end up in a place where you have:

  • An Azure Mobile Service containing your .NET web API code
  • That service registered within your Azure AD tenant
  • A native iOS app registered within that same Azure AD tenant
  • That client accessing the Azure Mobile Service

Next Steps

To this working solution we will now add secure connections to resources located “behind the firewall”.  In this example, one of these resources is a Web API running in Visual Studio/IIS Express on my laptop.  The other resource is a SQL Server running in Microsoft Azure.  Not exactly on-premises, but the network is obfuscated so it’s still a good example.  I’m using Visual Studio 2013 Update 3.

Step 1

If you haven’t already, create an Azure BizTalk Service in the Azure Portal.  You’ll need to specify a name, any tier of service (including the Free (Preview) tier) and a region.

Step 2

On your development machine create a new solution based on the ASP.NET solution template.  Select the Web API variant.  There is no need to add any code.  Run the app by pressing F5.  For simplicity’s sake leave it on port 80, but if IIS Express remaps it, take note of the port.

Step 3

Within the BizTalk Service, create a Hybrid Connection (HC).  You’ll need to specify a name for your HC plus the host name and port.  For the host name of the HC for the Web API, specify your dev box’s ComputerName.  This is the name you’ll use in your mobile service code to connect to it, along with the TCP port 80 or whatever IIS Express remaps to in step 2.

Step 4

Highlight your HC in the list; click the toolbar button labeled “On-Premises Setup”.  This will cause a download window to pop up.  Install the Hybrid Connection Manager (HCM) on your dev box.  Installation also accomplishes configuration.  If you take a look in C:\Program Files\Microsoft\HybridConnectionManager\Microsoft.HybridConnectionManager.Listener.exe.config, you’ll see the on-premises connection string.  This connection string may also be viewed in the portal by clicking Manage Connections in the toolbar for the HC.

Step 5

Validate connection.  Once the HCM is installed and configured on your machine, you should see in the list of HC’s that its status is “1 instance connected”.  If it doesn’t, your HC won’t work.  You’ll need to diagnose and fix this before moving on.

Step 6

Configuration of IIS Express.  When you run your API in Visual Studio, IIS Express creates a binding for local access to your Web API by default – something like https://localhost:31106/.  In order to accept connections coming across your HC, you need to add a binding such as: https://ComputerName:31106.  Of course, change 31106 to match the port that IIS Express assigns to you.  Under normal circumstances, you would also need to add a URL ACL using netsh.  But since we’re using an HC, the connection appears to be coming from on-box so this step isn’t necessary. Neither do we need to configure the firewall at all.  Here’s what it looks like in my applicationhost.config:

 <bindings>
  <binding protocol="http" bindingInformation="*:31106:localhost" />
  <binding protocol="http" bindingInformation="*:31106:golivex1" />
</bindings>

And just so we’re super clear, the host name of the HC is your computername. And in the <binding you add to applicationhost.config is also your computername (mine is golivex1).

For more details, skip down to the “Serving External Traffic” section of this page:

https://www.iis.net/learn/extensions/using-iis-express/handling-url-binding-failures-in-iis-express

Step 7

Repeat steps 3-5 for the other HC that you’ll be needing. The host name for this one is the name of the SQL Server box. You can use one on your premises or one in an Azure VM.

Step 8

Go into the Configuration page of your mobile service. About halfway down the page you’ll find Hybrid Connections. Add your two HC’s to the list and Save (button in the toolbar at the bottom of the page.)

Step 9

If you’re following along, you have a Web API running as an Azure Mobile Service. Within the controller of that app (TodoItemController) there is an API “POST tables/TodoItem” with signature:

 public async Task<IHttpActionResult> PostTodoItem(TodoItem item) 

This API is hit whenever the user adds a new Todo Item in the client side app. And, if you’re following along, the client side is the iOS app. Within this POST, add code such as the following to reference each resource – SQL Server and the Web API running on your dev box created in Step 2.

 // use the sql server connection
try
{
  SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
  builder["Data Source"] = "myserver";
  builder["Integrated Security"] = false;
  builder["Initial Catalog"] = "mydb";
  builder["User ID"] = "greg";
  builder["Password"] = "S3cr3t";

  int count = 0;
  string query = "SELECT COUNT(*) FROM mytable";
  using (SqlConnection conn = new SqlConnection(builder.ConnectionString))
  using (SqlCommand cmd = new SqlCommand(query, conn))
  {
    conn.Open();
    cmd.CommandType = System.Data.CommandType.Text;
    count = Convert.ToInt32(cmd.ExecuteScalar());
  }
  string results = string.Format("Count of records in tbPerson is {0}", count);
  Services.Log.Info(results);
}
catch (Exception ex)
{
  Services.Log.Error(ex.Message);
}

// use the web service connection
try
{
  const string URL = "https://mydevbox:31106/";
  HttpClient client = new HttpClient();
  client.BaseAddress = new Uri(URL);

  client.DefaultRequestHeaders.Accept.Clear();
  client.DefaultRequestHeaders.Accept.Add(
  new MediaTypeWithQualityHeaderValue("application/json"));

  string response = await client.GetStringAsync("api/values/5");
  Services.Log.Info("Accessing the web service succeeded.");
}
catch (Exception ex)
{
  Services.Log.Error(ex.InnerException.Message);
}

In the SQL Server Data Source of the above code snippet is the host name of the HC for SQL Server (port 1433 assumed), and in the URL of the HttpClient is the host name and port of the HC for the Web API resource on the dev box. SQL Authentication was used on the SQL Server.

Step 10

The final step is to fire up your iOS client and add a new todo item to the list. To verify success, take a look at the logs of the mobile service. The easiest way to do this is to View the Server Explorer in Visual Studio. Expand the Azure branch of the tree, then the Mobile Services branch. Right-click your mobile service and “View Logs…” For more details:

https://msdn.microsoft.com/en-us/library/azure/jj193163.aspx

Final Thoughts

If things don’t go perfectly the first time and you decide to edit the configuration of your HC’s, you’ll need to restart the HCM on your dev box AND remove/re-add the HC in your mobile service to ensure configuration changes are replicated all up and down the line.

Cheers!