Protect Your ASP.Net Web API Using Azure ACS Service Identities

Web 2.0 has lately been characterised by the increased proliferation of APIs available for consumption that create a “web of APIs” and open up the web for new businesses such as Stackla.  In this post I am going to cover how you can utilise Windows Azure Access Control Services (ACS) as a Security Token Service (STS) to centralise and simplify authentication of external callers to your ASP.NET Web API using Simple Web Tokens.

A bit on Access Control Services (ACS) and Claims-based Authentication

Access Control Services has been one of the core Azure components for well over two years now and provides a simple (yet scalable and highly available) platform on which pretty much any application can rely for authentication (even if the application is not sitting on Azure!)  ACS also provides you with an easy way to have a single integration point that provides logon support from Microsoft Accounts (formerly Live ID), Google, Yahoo!, Facebook, ADFS v2.0 and any endpoint supporting OpenID.

Understanding ACS requires some understanding of the main actors in a generic claims-based authentication system:

  • Client Application: Any user or system that wishes to use the services of the Relying Party and must be authenticated in order to do so.  In this post our Client will be a simple Windows console application.
  • Relying Party (RP): As the name suggests it will rely on another actor in the claims process to authenticate its callers.  Importantly the RP must have a trust relationship with the STS. For the purposes of this post the RP will be our Web API.
  • Identity Provider (IdP): the ultimate source of the identity which will be used for authentication (and potentially authorisation).  This may be a Microsoft Account or other third-party IdP such as Facebook.  When using ACS you can also choose to use Service Identities where ACS is responsible for managing identities as well as issuing tokens – this will be what we are using for this post.
  • Secure Token Service (STS): the coordinator that sits in the middle of everything and is responsible for issuing tokens on behalf of Identity Providers.  These tokens are then passed to Relying Party applications. As previously noted, the STS must be trusted by any RP utilising its services as the RP has effectively delegated authentication.

Create a Web API Demo Application

… or bolt the necessary authentication code into your existing Web API.

The easiest way to wrap you head around the concepts in this post (and a good way to get the code necessary for your implementation) is to head over to the MSDN samples site and download the sample titled “MVC4 Web API With SWT Token Issued By Windows Azure Access Control Service (ACS)“.  This will provide you with a quick way to test out the key scenario described through the remainder of this post.  You’ll need to do the next section before you can run the code (it will compile OK but won’t work as you’re missing the authentication piece of the puzzle!)

Provision and Configure ACS

I’m assuming here that you already have an Azure subscription – if not you will need to go and sign up for one – you get a 90 day free trial (at time of post) and then after that you only pay for what you use.

Before you can use ACS you must set up a namespace that will be used as the unique identifier for your little piece of the ACS service.

1. Log into the Azure portal and click the + NEW button in bottom left > App Services > Access Control > Quick Create.

ACS Quick Setup

2. Enter a unique namespace for your ACS instance.  The console will tell you if the namespace you’ve provided is unique and stop you from creating a duplicate.

3. After a short period of time the new ACS namespace will be provisioned and you can navigate to the management console for it by selecting the ACS namespace from the All Items view in the Azure portal and click “manage” at the bottom of the screen.  This will open the ACS management screens which are based (at time of post) on the old Azure portal look and feel.  Note the URL:

4. Add a new Relying Party Application and specify the following (if a field isn’t mentioned leave as its default):

  • A Name that describes your Web API and differentiates it from any others you may have (think also about dev / test / prod requiring their own RP definition).
  • A Realm that will be used to scope the issued Token.  Again, the Realm will most likely differ between environments, are case sensitive and are typically represented by a URL.
  • Token format of SWT (Simple Web Token).
  • Token lifetime.  The default is 10 minutes.  Think about how this value may affect your architecture – do you need to revalidate the token more or less often than this? Do you want to cache the token at your client application for a period to reduce chatter with ACS?
  • Uncheck Windows Live ID for Identity Providers (this will cause ACS to use its own Service Identities).
  • Under Rule Groups leave “Create new rule group” checked.
  • Generate a new Token signing key (Note: this is important – this will be used in your Web API to validate the incoming Token).
  • Click Save.

5. Now we need to define the Rules for the Relying Party Application we just defined in step 4:

  • Click on “Rule groups” on the left navigation and select the rule group you just created.
  • Click on “Add” at the bottom of the screen.
  • On the Add Claim Rule screen select “Access Control Service” for the Input Claims Issuer.
  • Scroll down and click Save.

6. Create a Service Identity for client applications (callers) to use when requesting a token from the STS:

  • Click on “Service identities” on the left navigation.
  • Click Add and then complete the form as follows:
    • Name: this will be a unique identifier for the identity AND will be used for the username in making a request to ACS.
    • Under Credential Settings select “Password” and then enter a strong password.
    • Set the validity date range.
    • Click Save.

At this point we’re done with our ACS configuration.  We can add / remove / invalidate Service Identities at any time which presents an easy way to control access to your API in a centralised place without needing to maintain a local access database.  You could also modify the SWT to provide additional context (or claims) if you wished.

Tie It Together In the Demo

Load the demonstration you download previously  into Visual Studio then make the following edits.

namespace TestClient {
    class Program {
             // App Code Removed
             static string serviceNamespce = "youraacsnamespace";
             static string acsHostUrl = "";
             static string realm = "http://yourrealm/";
             static string uid = "yourserviceidentity";
             static string pwd = "yoursupercomplexhardpassword";
             // App Code Removed

namespace MVC4WebAPI.Services.ACS.SWT {
     public class TokenValidationHandler : DelegationHandler {
            string serviceNamespace = "youracsnamespace";
            string acsHostName = "";
            // comes from step 4 above
            trustedTokenPolicyKey = "**********************";
            trustedAudience = "http://yourrealm/";
            // App Code Removed

Now you can run the demo code and you should see a successful result returning a simple value array like the default Web API project does in ASP.Net.

Demo Output
Try changing one of the elements that you pass to the code and see what the result is – you should see that you receive a 401 Unauthorised. Note that in a production-ready system you’d not expose the reason for the failure as they do in the demonstration code but it’s useful as a way to understand what code is being processed and is causing the authentication failure.

Hope you find this content useful – if you have any feedback, tips or other useful information please feel free to leave a reply below!

11 thoughts on “Protect Your ASP.Net Web API Using Azure ACS Service Identities

  1. Service identity is stored in cloud service. How you can ensure that Microsoft Azure team will not steal your Identity?

    Is it possible to secure my symmetrickey, uid and pwd protected?

    1. Ashekur, I guess you work on trust and rely on the veracity of the operational procedures that the Azure team uses when managing their environments. Public cloud providers typically have several layers of control that mean your tenant data is pretty much locked away from any Azure operational staff. See this page for the Windows Azure Trust Center for more details.

      The key, username and password are only for the purposes of authentication for the current API consumer so the potential impact is relatively low in the event they are exposed and you can easily disable the service identity if necessary.

      1. Thanks Simon for your reply. If token life time is 30 days (for example), then third party application can acces user resources during this period.

        I may disable the service identity but user may loss his resources before that if Azure operational stuff stole ACCESS TOKEN. Do you agree?

      2. I am actually asking this question because, I want to create Mobile APPs. User will access the API from the Mobile APP (third party app). When user will click the Login button he will be redirected to my Authorization server for ACCESS TOKEN. APP will then call the API for the resources. I don’t want to keep the user’s credential in Phone memory (third pary app). Anyone can download my app and understand the URL (HTTP) to access the resource. If Azure team exposes my ACCESS TOKEN then haker can access my resources.

        For the above scenario, should I follow this authentication process if I don’t trust Azure team?

      3. Ashekur, I’d probably stop you there and ask why you would host your application on Azure if you don’t trust it – this would seem fundamental as to why you would select any hosting partner (cloud or otherwise). Any solution you come up with will ultimately be subject to potential MitM-type attacks if you assume that any administrator at your hosting company has access to the systems that transport your data and can do what they please (see this great blog from Troy Hunt on how SSL is even theoretically open to abuse using fairly simple means).

        Also, there is more than one way to achieve what I blogged about (see this Technet Post or this MSDN article) that may sit better with you, but ultimately the core question for you seems to be about trusting how the platform is operated and maintained.

  2. “For the above scenario, should I follow this authentication process if I don’t trust Azure team?”

    If you don’t trust the Azure team, don’t host on Azure! I say this not because of ACS, but because it’s the one critical component of an online system that you absolutely, positively have to trust – the hosting provider. If you make the assumption that the host is nefarious – whoever that host may be – then it’s game over already. They can sniff your traffic behind the point where the SSL terminates (hi NSA!), they have direct access to your database and they can manipulate your application code. Basically, if your host is evil, you’re stuffed.

    IMHO, do your due diligence and select the host you have *the most* trust in. For me personally, that’s the likes of Azure and Amazon. They’ve invested the most and have the greatest oversight on their processes. I trust them with my apps.

    1. Sorry Troyhunt!
      I am not hosting my REST service on Azure. Only I need ACS to issue access_token.

      If you want to protect your service deployed to Azure then it is OK. But if I want to protect my service hosted in my own domain then will it work?


      1. You’re hosting a component of your app ecosystem on Azure. Regardless of whether it’s the DB or the UI or a security construct, only use the service if you trust the team behind it!

  3. Thank you for the sample and detailed instructions. This works great! However, do you know of a sample that has the Client authenticate itself via another Identity Provider (e.g. FB) instead?

Leave a Reply to Simon Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s