No more excuses; protect your (Azure) Soap/rest API, ALWAYS! – End-to-End Scenario part 1

 

Intro

you don’t want to know, how many times I’ve encountered web apps / API’s which are publically accessible and as such don’t use any form of authentication whatsoever. So please do me a favour. From now on please protect your APIs.

Azure really makes this easy, especially with the recent (preview) release of URL Authorization and having the Azure Active Directory management functionality available in the new portal.

This blogpost will detail an simple but effective end to end scenario in which we will be leveraging

 

End-to-End Scenario

The scenario which we are going to build is a fairly simple one and merely encompasses retrieving customer information. However to make it a bit more interesting the customer information which is to be returned combines two API calls. The initial call will be towards our, by AAD protected ‘CRM’ system (using a WCF Service) and the second call will be going towards a public postal code lookup service (RESTful). The data returned from both of these API’s will then be combined and returned to the user.

The whole end-to-end scenario will be discussed in a few blogposts, and this first post will focus on publishing a WCF service and protecting it using Azure Active Directory and URL Authorization.

If you’ve been reading my blog for a long time, you will now that I tend to be pretty elaborate and this blogpost is no difference. So yes you might want to skip some items as you might already be familiar with it.

Create the customer WCF service

So let’s start of with building the sample customer WCF service. For simplicity sake I named this service SimpleSoapService and all it does is return a ‘fixed’ set of customers when invoked.

So first of create a new WCF service using your favourite IDE, in my case Visual Studio Smile

1) In VS select File –> New
2) Select Project

SNAGHTMLf0466a0

3) Search for WCF in the searchbox
4) Select WCF Service Application
5) Enter the required details (Name, Location and Solution Name)

SNAGHTMLf126ce5

6) Delete the IService1.cs and Service1.svc file
7) Add a new WCF service, by right clicking on the WCF project –>  add a new item

image

8) Name the service for example Customers.svc

image

9) Create a new class, by right clicking on the WCF project –> Add and select Class

SNAGHTMLf2039bb

10) Name the class CustomerData

image

11) Copy and paste the following code into the class. This code will be a representation of the data to be returned

using System;
using System.Runtime.Serialization;

namespace CustomerService
{
[Serializable]
[DataContract]
public class CustomerData
{
[DataMember]
public int CustomerId { get; set; }

[DataMember]
public string FirstName { get; set; }

[DataMember]
public string SurName { get; set; }

[DataMember]
public int PostCode { get; set; }

}
}

12) Now open the ICustomers.cs file and paste the following code (this is the interface class which dictates the service operation to expose)

using System.Collections.Generic;
using System.ServiceModel;

namespace CustomerService
{

[ServiceContract]
public interface ICustomers
{
[OperationContract]
List<CustomerData> GetCustomers();

}

}

13) Now open the Customers.svc.cs file (expland the Customers.svc) and paste the following code (this class implement the ICustomers interface)

using System.Collections.Generic;
namespace CustomerService
{
public class Customers : ICustomers
{
public List<CustomerData> GetCustomers()
{

return CustomerFactory();
}

private List<CustomerData> CustomerFactory()
{
var result = new List<CustomerData>()
{
new CustomerData()
{
CustomerId = 1,
FirstName = “Rene”,
SurName = “Brauwers”,
PostCode = 2034
}
};

result.Add(new CustomerData()
{
CustomerId = 2,
FirstName = “Mick”,
SurName = “Badran”,
PostCode = 2031
});

result.Add(new CustomerData()
{
CustomerId = 3,
FirstName = “Crocodile”,
SurName = “Dundee”,
PostCode = 4880
});

return result;
}
}
}

Deploy the customer WCF service

Now that we have created our WCF service, we are ready and can deploy the service into Azure.

In order to do so, you will require a Azure Subscription. If you do not have a Azure Subscription, you can sign up here for a free trial

1) From within VS.Net, right click on your WCF service and select Publish…
SNAGHTMLf455399

2) The publishing Wizard will now popup, on the initial screen; select the publish Target “Microsoft Azure App Service”

image

3) Select your Azure Account (if there is no account available, you need to select Add a new account)

image

4) As I’ve already added my account, I selected my main account and choose the Azure  Subscription to use, and selected Resource Group as View and then selected NEW to create a new App Service.

image

5) On the initial screen fill out the required details, which consist of

  • the Web App Name (Name of the web application to deploy – your wcf service)
  • the Azure Subscription in which the app will be deployed
  • the resource-group to deploy to (you can select an existing Resource Group or create a new one (using the new button). In my case I selected an existing resource-group)

image

  • the App Service Plan to use (you can select an existing app service plan, or create a new one. In my case I created a new one. Creating a new App Service Plan is straight forward as well. Just select the NEW button next to the App Service Plan.

image

  • After you’ve pressed the new button, you simply fill out the required information consisting of the name for the App Service Plan, the location (data-centre) to deploy to and the size (pricing tier)

image

6) Now that you’ve entered all the data, you can click on the Create button. Which will provision the App Service and the Web App.

image

7) Once provisioned, the publish screen will appear. Leave the defaults and select the Publish button.

image

8) Once the site has been published a browser window will pop up pointing to your web app.

image

Test customer WCF service

Now that you’ve published the webservice it is time to test if everything works. The easiest way to test the service would be by means of SOAPUI. So in case you don’t have SOAPUI go and download it here

1) Go ahead and start SOAPUI once it is installed

2) Now in order to test the webservice we will need to WSDL and import it into SOAPUI. The WSDL can be downloaded by browsing to your web-app which you just deployed. In my case the endpoint address would be “http://customerwcfservice.azurewebsites.net/Customers.svc”

3) Now copy any paste the WSDL address (http://customerwcfservice.azurewebsites.net/Customers.svc?singleWsdl)

you can choose from two options, which one you choose does not matter for SOAPUI. In my case I selected the singleWSDL one as this ensures that the whole web-service description is contained in one single file and as such it does not reference any other files. I usually choose this option to avoid any potential issues importing as some clients have issues importing a WSDL which has dependencies on multiple files)

image[65]

3) In SOAP UI, select the SOAP button to create a new project

image

4) Now add the WSDL into the appropriate text box and press OK

image

5) Now open the Request 1 item in the GetCustomers node

SNAGHTMLf754e5f

6) Click on the Play button, to test your webservice

image

7)  Your webservice should return a list of customers, which indicates that everything is working Smile

image

Secure your WCF Service

Finally now we get to the fun part. Securing your WCF service! As I mentioned in the introduction; Azure really makes securing your web apps easy.

So let’s get started with adding URL Authorization to the earlier created WCF Service.

Enabling AAD as authentication provider for our web-app

1) Go to the Azure Portal and select All Resources

2)  search for your web app which you created earlier, in my case this is CustomerWCFService

3) Click on it

image

4) A blade with all settings will now appear. In this blade select the Authentication / Authorization item (part of settings)

image

5) Enable App Service Authentication On the Authentication / Authorization screen

image

6) Leave the Allow Anonymous requests (no action) setting

image

7) Click on the Azure Active Directory Authentication Provider

image

8) Select Express as Management mode

image

9) Select Create New AD App and press OK

image

10) Press the Save Icon

image

Protecting our web-service

Now we’ve set up the initial authentication / authorization part it is time to actually protect our web-service.

In order to do so, we will be required to add a Authorization.json file to our www-root directory.

This file will contain information of which web resources to protect (Ie which require a user to be authenticated). In our scenario we will set it up such that a user will be able to obtain the WSDL, however posting to the webservice will require a user to be authenticated.

In short we want GET operations to be allowed and a POST operation will require a user to be authenticated. To meet these requirements the contents of the Authorization.json file needs to be as follows

{
“routes”: [
{
“http_methods”: [ “GET” ],
“path_prefix”: “/”,
“policies”: {
“unauthenticated_action”: “AllowAnonymous”
}
},
{
“http_methods”: [ “POST” ],
“path_prefix”: “/Customers.svc”,
“policies”: {
“unauthenticated_action”: “RejectWith401”
}
}
]
}

The configuration mentioned above, indicates that all GET operations are allowed and that POST operations to /Customers.svc require a user to be authenticated.

Please note; adding the authorization.json file to you vs.net project and making it part of your deployment, will cause an error. “The page cannot be displayed because an internal server error has occurred.”  This is most likely due to the fact that the feature is currently in preview. Looking at the log indicates that there is a deserialization issue.

System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type Microsoft.Azure.AppService.Routes.RoutesConfig. Encountered unexpected character ‘ï’. —> System.Xml.XmlException: Encountered unexpected character ‘ï’.

In order to resolve this issue we will be adding the authorization file manually by leveraging the App Service Editor from within the Portal Smile. Which is being described below:

Enabling authentication

1) On our settings blade of the web app, scroll down to the DEVELOPMENT TOOLS section and click on App Service Editor (preview)

image

2) Click on the GO link, which will redirect you to the online editor.

image

3) In the online-editor, right click on the wwwroot and select New File

image

4) Name the file Authorization.json

image

5) Copy and paste the following contents

{
“routes”: [
{
“http_methods”: [ “GET” ],
“path_prefix”: “/”,
“policies”: {
“unauthenticated_action”: “AllowAnonymous”
}
},
{
“http_methods”: [ “POST” ],
“path_prefix”: “/Customers.svc”,
“policies”: {
“unauthenticated_action”: “RejectWith401”
}
}
]
}

6) Your file will be auto-saved and as authentication enabled which will require POST operation to the customer service to be authenticated.

image

Test the protected webservice

Before we can test if the authentication part is working, it is required to restart the web-app (this is only a temporary workaround, once the url authentication feature goes GA this will no longer be required). Once restarted we can go ahead and test the web-service.

1) Go back to our web-app blade in the portal and click on the overview item.

image

2) We now can see options to restart the web-app. Click on it

image

3). Now browse to your web site, and you should notice that it will display the Customer Service page (It is a get operation, which is allowed)

image

4) Now go back to SOAPUI and try to execute the webservice. uOu will notice that you will receive a 401, as this one requires you to be authenticated.

image

Conclusion

This post has guided you through setting up a WCF service and protecting it using URL Authentication. Although the post was lengthy you will notice that setting up url-authentication is actually quite simple and only involving a few steps.

Anyways, In my next post we will be further expanding on our end-to-end solution focusing on Logic Apps and API Management.

So stay tuned.

Cheers

René

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *