Exposing any on-premise WCF Services in Azure
Exposing your on-premise Web Services to the outside world can sometimes be a hassle. While sending data from inside the corporate network to the outside world is often fairly easy, the reverse is most often much more difficult and also more of a security risk.
The Microsoft Azure Service Bus holds a very clever and very cool solution for this: The Service Bus Relay. However, many of the samples found on the Internet for using this great tool, is using the Service Bus Framework code supplied by Microsoft for exposing your Service in Azure, and does not show how this is done to an existing WCF Service already deployed and running in your local on-prem environment.
This article will show you just how to do that, using Shared Access Signature (SAS) to securely communicate between your local environment and the cloud.
This blog is not about creating WCF Services, and therefore I will assume that the reader already has at least one existing service running locally on-premise. I also assume that you have a running Microsoft Azure subscription with credits.
For my demo I have created a small Visual Studio WCF Service named WeatherService; created a single operation GetCurrentWeather, that takes a string as input (City) and returns a string as output (current weather situation in the current city).
My Service is, for now, just running in Visual Studio (IIS Express) and I have tested that the service is working, by calling it through SOAP UI.
So before we dig into the Azure part of exposing a Web Service, it is important that you have a local Web Service and you are able to test that your service is running and working (and that your test tool / test program has the ability to change the service-address later in the process).
Creating a new Service Bus Namespace in Azure
As of April 2016, the Service Bus part of Azure, has not been lifted to the new Azure Portal (portal.azure.com), so if you are using the new portal, just type B (for browse) -> Type Service Bus in the Filter TextBox, and select Service bus namespaces.
You should now be redirected to the old portal (sign in might be required again), and placed in the Service Bus Tab, appearing some like this:
If you don’t already have a Namespace that you want to use, create a new one:
- At the bottom of the page select CREATE
- Choose a unique NAMESPACE NAME (the small icon-indicator will let you know if the namespace chosen is valid)
- Choose the correct REGION and SUBSCRIPTION (leave TYPE and MESSAGING TIER as they are) **
** You need at least STANDARD Type for using the Relay functionality, read more about the different types here:
Select the OK (Check mark) icon, and the namespace should start being provisioned and should, within a few seconds, appear in your list as Active.
Adding a policy to the namespace
We are almost done in the porta, but before starting configuring our local service to expose itself in our newly created Service Bus namespace, we will configure a Shared Access Policy (SAS) to the namespace, that allows our service to listen to service-requests exposed in the namespace.
- Choose your namespace by selecting it
- Once inside your namespace, choose CONFIGURE
- Create a new policy named Listener, and grant the policy the Listen-permission
- Select SAVE
- Once saved, you should be able to select your newly created policy in the POLICY NAME list under shared access key generator
- Once selected copy the PRIMARY KEY (click the copy-icon) and save the policy name (Listener) and your key in a text document (as we will need these later)
Exposing our Service in the Cloud
Believe it or not, but we are almost done!
All we need now is to download a Microsoft Service Bus DLL and include a few line of XML in our web.config file of our existing service.
Download the Microsoft.ServiceBus.DLL
This dll can be acquired in a NuGet package.
- Create a small sample Visual Studio C# Console Application
- Once created, open the Package Manager Console
- Tools -> NuGet Package Manager -> Package Manager Console
- In the PM-Console type: Install-Package WindowsAzure.ServiceBus
- Once the package is installed, locate the Microsoft.ServiceBus.DLL in your solution folder structure
- Should be located somewhere like the following:
- Should be located somewhere like the following:
- Copy this dll to the /bin folder of your local Service that you want to expose in Azure
Altering the web.config
I assume that you already have a running WCF Service and that the service contains a web.config file (could also be an app.config file, if you are running a WCF Service Host as a console-app etc.).
Your config file should contain a system.serviceModel record, looking somewhat similar to this:
Please note that my sample Service is very simple. Your config file might contain more information about security etc.
Immediately after the opening system.serviceModel record, insert to following:
<add name=”transportClientEndpointBehavior” type=”Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />
<add name=”basicHttpRelayBinding” type=”Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />
<add name=”ws2007HttpRelayBinding” type=”Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />
You have now registered both two new bindings (basicHttpRelayBinding and ws2007HttpRelayBinding), and a new behavior (transportClientEndpointBehavior). These will be used for communicating with our Service Bus namespace from our local Service.
Note: ws2007HttpRelayBinding is not used in this demo. It only needs to be present if you are going to expose meta-data in the Service Bus.
Adding an Endpoint behavior
Now we will add an endpoint-behavior that holds our policy token (for this you will need the policy name and key, written down earlier from the portal).
Inside the behaviors record append the following:
<sharedAccessSignature keyName=”Listener” key=”%Your_Key_Copied_Earlier%” />
We now add a binding configuration telling the relay service that everybody can access our service.
This may or may not be the appropriate solution, but for this demo I will not dig into incoming Azure security. Just remember that any security already applied to your local Service! (not endpoint, but Service!) will automatically be exposed in the cloud Service.
After the services record append the following (note: if you already have a bindings record, just append the inside XML into that):
<security relayClientAuthenticationType=”None” mode=”None” />
Adding our Azure Endpoint
And now we are ready for the final addition: the actual endpoint in Azure!
Inside your services/service record insert the following:
And now we’re done!
Your configuration should look something like this:
Now go to your local service (which still should be browsable), and refresh the page. You should notice that the refresh takes a second or two. Once the page is refreshed, it should be exposed in Azure and everybody can call it.
To verify go to your Azure Service Bus namespace in the portal, and choose RELAYS
Verify that the service is exposed and running:
Tesing the newly created Azure endpoint
Now all you need to do is take your test tool, and point it to the azure address instead of your local address (in my case: http://verticablog.servicebus.windows.net/WeatherService)
You should now get the exact same result as when you were calling your service locally, and now:
Everybody can utilize your service from all over the world!