Ok …This is in continuation of my previous blog here. Now we are going to integrate ACS with our cloud hosted WCF data service. Following are the steps taken :

  • Create a ACS Namespace
  • Add our Cloud hosted WCF service as Relying Party in ACS namespace
  • Add service identity with the user credentials to be passed from the client in ACS namespace
  • Add claim rules in a rule group associated with your relying party
  • Create an HTTP Module in Cloud Service Web role to intercept when ever a request comes in, it will check whether there is a token in the authorization  header and validate the same. If a valid token is found, access is granted otherwise the request is marked unauthorized
  • Fire request from client(Windows Store Application) using the service identity user credentials configured for the ACS

So lets get started..

-Create a new ACS Namespace from Azure Portal


-Click on Manage on the ACS Namespace created to open the ACS Portal from Azure portal


-Configure your Cloud Service WCF Data Service url in the realm and return url on the Relying Party Applications section

We will be using Single Web Token(SWT)


-Add Service Identity to authenticate directly with ACS and receive security tokens. These credentials will be included in the client request to authenticate itself


-Add Claim Rules in a rule group associated with your relying party or generate pass-through rules using the rule group editor


-Finally Add an HTTP Module in your Cloud service project to intercept every request and check for the Authorization header to

check if a valid token is sent from the client. Republish the service to Azure with the security integrated.

public class SWTModule : IHttpModule
       //Use a configuration file to manage this data
       string acsHostName = "accesscontrol.windows.net";
       string serviceNamespace = "wcfacsnspace";
       string trustedTokenPolicyKey = "[YOUR TOKEN SIGNING KEY";
       string trustedAudience = "[YOUR CLOUD SERVICE RELYING PARTY URL]";

       void IHttpModule.Dispose() {}

       void IHttpModule.Init(HttpApplication context)
           context.BeginRequest += new EventHandler(context_BeginRequest);

       void context_BeginRequest(object sender, EventArgs e)
           string headerValue = string.Empty;
               //if (!HttpContext.Current.Request.IsLocal)
               //Handle SWT token validation
               // Get the authorization header
                headerValue = HttpContext.Current.Request.Headers.Get("Authorization");

               // Check that a value is there
                if (string.IsNullOrEmpty(headerValue))
                   throw new FaultException("Unauthorized");




<add name="SWTModule" type="WCFServiceWebRole.SWTModule, WCFServiceWebRole" />


Now if you try to access the service url from the browser, an unauthorized access error is received

Accessing the service from Windows Store App Client

-Create a Windows Store Application and get token from ACS passing in the realm and set the authorization header.

string token = await TokenReceiver.GetTokenFromACS(realm);
            header = string.Format("WRAP access_token=\"{0}\"", token);

           MySampleDBEntities context = new MySampleDBEntities(new Uri(realm));
           context.SendingRequest += context_SendingRequest;

           DataServiceQuery<PersonInfo> query = (DataServiceQuery<PersonInfo>)(
               from item in context.PersonInfoes
               select item);

static void context_SendingRequest(object sender, SendingRequestEventArgs e)
          e.RequestHeaders["Authorization"] = header;

public class TokenReceiver
       static string serviceNamespace = "[YOUR ACS NAME SPACE]";
       static string acsHostUrl = "accesscontrol.windows.net";
       static string wrapUsername = "[USER ID IN SERVICE IDENTITY]";
        static string wrapPassword = "[PWD IN SERVICE IDENTITY]";

       public static async Task<string> GetTokenFromACS(string scope)
           // request a token from ACS
           HttpClient client = new HttpClient();
           client.BaseAddress =new Uri(string.Format("https://{0}.{1}", serviceNamespace, acsHostUrl));
           HttpContent content = new FormUrlEncodedContent(new[]
                new KeyValuePair<string, string>("wrap_name", wrapUsername),
                new KeyValuePair<string, string>("wrap_password", wrapPassword),
                 new KeyValuePair<string, string>("wrap_scope", scope)
           content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

           var result = await client.PostAsync("WRAPv0.9/",content);
            byte[] responseBytes = await result.Content.ReadAsByteArrayAsync();
           string response = UTF8Encoding.UTF8.GetString(responseBytes, 0, responseBytes.Length - 1);

           return System.Net.WebUtility.UrlDecode(
               .Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))

When the client provides token received from ACS to the Cloud Service using the Service identity credentials, the service functionality is accessible to the client


Learn and enjoy Smile !!!!!

A quick disclaimer: The posts/opinions over here are my own views and not of my employer.