Introduction:
Windows Azure platform AppFabric provides us with the services to build applications that work across different networks in a secure manner. Windows Azure platform AppFabric has two main parts to it as follows:
- Access Control: Access Control part of the Azure AppFabric takes care of the authorization part. This authorization is done only for REST based web services a.k.a. RESTful web services.
- Service Bus: The Service Bus is used to facilitate communication between disparate systems across their respective network boundaries.
The "AppFabric" discombobulation:
There are primarily two products by the same name, AppFabric. So to prevent the confusion, a very short description of both the types:
- Windows Server AppFabric: It is used to build and manage applications that run on the IIS. It is a combination of two technologies with the code names 'Dublin' (for building and managing apps) and 'Velocity' (for caching) respectively.
- Windows Azure platform AppFabric: Same as explained in the introduction part. We shall discuss Azure platform AppFabric technology in this article.
For the sake of simplicity, in this article, we would be referring to 'Windows Azure platform AppFabric' as 'AppFabric'.
Scope:
The article deals with an overview about the working of the AppFabric Access Control. We shall begin with what the Access Control in Windows cloud is all about, how we can set this up to suit our requirement. We shall then conclude with a sample client code snippet which uses the Access Control to seek the token to access any RESTful web service.
In a follow-up article to this, we shall delve into the Service Bus part of the AppFabric and sample code snippets of a RESTful web service which can accept and validate the claims sent by a client and return an appropriate response.
For in-depth explanation of the Access Control Service, one can refer to a very well written paper by the name 'A Developer's Guide to Access Control in Windows Azure platform AppFabric' by Keith Brown.
Claims based authorization:
In the claims based authorization model, a client sends a service a set of claims. These claims are primarily a set of information, which helps the service to identify a client. Based on the information received in the claim, the service identifies the client and processes its request accordingly.
The claims can be anything, ranging from the 'name' of the client to the 'role' that the client plays. However, the claims desired by a particular service are pre-decided between the service and the client.
Simple Web Token (SWT): SWT is a token format developed jointly by Google, Microsoft and Yahoo. This token format is used to send claims to the RESTful web services. An example of a SWT is as follows:
MethodName=GetData&Issuer=https%3a%2f%2fsaurabhvartak.accesscontrol.windows.net%2f
&Audience=https%3a%2f%2fsaurabhvartak.servicebus.windows.net%2fService
&ExpiresOn=1273861972&HMACSHA256=nNOXnhZl4wcoUsRanEDkEGFTjOe0QKT25LyLa5mhKYw%3d
Here, the claims appear in the key-value pairs with different pairs separated by '&'. Hence, in the above example, the keys and their corresponding values are as follows:
MethodName=GetData
Issuer=https%3a%2f%2fsaurabhvartak.accesscontrol.windows.net%2f
Audience=https%3a%2f%2fsaurabhvartak.servicebus.windows.net%2fService
ExpiresOn=1273861972
HMACSHA256=nNOXnhZl4wcoUsRanEDkEGFTjOe0QKT25LyLa5mhKYw%3d
In the above key-value pairs, an Issuer is usually the entity which issues the token (in our case it is the ACS), Audience is usually the RESTful service to which the SWT needs to be sent, ExpiresOn is the token expiry date (counted as seconds elapsed since 1/1/1970 midnight UTC). MethodName is a user defined key-type (we can have our own keys and corresponding values in SWT). The keys are referred to as 'ClaimTypes' and the values are referred to as 'ClaimValues'.
The keys 'Issuer', 'ExpiresOn' and 'Audience' are the reserved words (but optional). Every SWT token has the only mandatory key-value pair by the key name 'HMACSHA256' and its key-value.
The role of the HMACSHA256 key and its value is primarily to verify that the claims that have been sent to it are from an authentic client and no one is spoofing them. The following steps explain how the HMACSHA256 key can be used to verify the authenticity of the claims:
In our example, the SWT is :
MethodName=GetData&Issuer=https%3a%2f%2fsaurabhvartak.accesscontrol.windows.net%2f
&Audience=https%3a%2f%2fsaurabhvartak.servicebus.windows.net%2fService
&ExpiresOn=1273863096&HMACSHA256=wtgVt4ZuZ01cuk%2fvxVQxk8rCa9XQccpqm%2b6OGZrNmcw%3d
Now the service which receives the SWT splits the SWT token into two parts as follows:
a. The part before '&HMACSHA256=' , which is:
MethodName=GetData&Issuer=https%3a%2f%2fsaurabhvartak.accesscontrol.windows.net%2f
&Audience=https%3a%2f%2fsaurabhvartak.servicebus.windows.net%2fService&ExpiresOn=1273863096
b. The part after '&HMACSHA256=' , which is:
wtgVt4ZuZ01cuk%2fvxVQxk8rCa9XQccpqm%2b6OGZrNmcw%3d
- Now, URL decode the part b of the token. We get the value as:
wtgVt4ZuZ01cuk/vxVQxk8rCa9XQccpqm+6OGZrNmcw=
- Whenever a SWT is exchanged between a client and a service, the service uses a key to verify the authenticity of the claims/client. Now for our example let this key be:
zOT21KxyIjvk299o2cIlU987B3/3KbH/cZf0W8DNO0Q=
- Next we compute the local-HMAC using the 'part a' and the key (mentioned in the above point). And we later Base64 encode the HMAC. We get the following value:
wtgVt4ZuZ01cuk/vxVQxk8rCa9XQccpqm+6OGZrNmcw=
- Now, the values obtained in points 2 and 3 match and hence a particular service can easily be assured that the claims sent are from an authentic client.
Details specs of the SWT format can be found in a well written white paper by Dick Hardt and Yaron Goland from Microsoft.
Now that we have discussed what the claims are and what SWT is, the question is where does Access Control fit?
AppFabric Access Control Service:
In plain simple words, Access Control Service provides the access control functionality using the claims based model to a RESTful service. ACS uses Web Resource Authorization Protocol (WRAP) to issue tokens.
The entire authorization scene works in the following sequence:
- The client requests a token from the Access Control Service by sending input claims. The request has the username, password and the service URL (which the client wants to access).
Kindly note that there are in all three methods to request a SWT. The one which we shall use here is the Plaintext method (where we pass the username and password in plain text). The other two methods are 'SAML bearer token' method and 'HMACSHA256 encrypted token'. - The Access Control Service verifies the username and password and then sends back the SWT. The SWT comprises of all the claims that the service expects. The service is the one which the client wants to consume.
- The client then invokes the service and sends the SWT to the service in the 'authorization' header of the http request.
- On receiving the request, the service extracts the SWT, verifies it (as mentioned in section 5.) and if all is well, processes the client request.
The following diagram explains the same:
Entities involved in the Access Control Service:
The below figure gives us an idea as to how the hierarchical structure of various entities involved in an ACS looks like.
A Service Namespace can comprise multiple Scopes.
Each Scope is a collection of different Rules and one Token Policy. Usually, a Scope is applied to a RESTful web service that we want to protect using the ACS. And hence a Scope name is usually the URL of the RESTful web service.
Each Rule is a collection of one Input Claim and one Output Claim. A Rule cannot be shared between multiple Scopes.
A Token Policy defines a few properties of a SWT like the Expiration time of the token and the Signature Key (mentioned in section 5.2). A Scope is mapped to a Token Policy. A policy can be applied to different scopes.
An additional entity that I didn't show in the diagram is Issuer. An Issuer is a key that the client sends to the ACS to seek claims (username and password mentioned in section 6.a)
Setting up claims in the Access Control Service:
a. Setting up the namespace:
- In order to have our own ACS in place, we need to first create a namespace under which the ACS will run. For the same, we need to log on to https://appfabric.azure.com/ using our windows live credentials for the Windows Azure account.
- We get a similar screen as shown below:
- Click on the desired project. You get the following screen. Click on the 'Add Service Namespace'
- We get the following screen. Now in the Service Namespace text box, key in the desired namespace and then click on 'Validate Name'. Select the desired region and the number of connections. And then click 'Create'.
- On clicking create, we get the following screen.
- Click on the newly created Service Namespace row. You shall see the screen filled with all the details pertaining to that particular namespace as follows:
Now that the namespace is created, our next step would be to set the desired claims for our service.
b. Setting up claims:
The claims can be set by using a management tool. The AppFabric SDK provides us with two such tools. One of them is ACM.exe (Access Control Management), which is a command line based tool. The second utility is called ACMBrowser. ACMBrowser is a GUI based management tool developed on WPF. We shall use the ACMBrowser utility.
(AppFabric SDK can be downloaded from http://www.microsoft.com/downloads/details.aspx?FamilyID=39856a03-1490-4283-908f-c8bf0bfad8a5&displaylang=en)
- Our first step would be to fire up the ACMBrowser Utility. The same looks as follows:
- Now, we enter our namespace that we created in our previous steps in the 'Service Namespace' textbox and we enter the management key. The management key can be found under the section 'Manage' on the Service Namespace screen as shown in section 8.a.6. After doing the same, we click on the Load from Cloud icon (the 'folder and cloud' icon).
If the details entered are correct, then we get the following pop up.
- It's time to create a new issuer. Now, under the 'Resources' section, do a right click on 'Issuers' and click 'Create'. Fill in the details as mentioned in the below screen. Don't forget to click on the 'Generate' button to generate the current and the previous keys. The keys obtained by you would be different than those shown below. Click on 'OK'.
The above generated key would be sent to the ACS to seek the claims. - Next step is to create the token policy. Do a right click on 'Token Policies' and click on 'Create'. Fill up the following details and click the 'Generate' button to generate the signing key. The generated signing key would be different in your case. Click on 'OK'.
The above 'Signing Key' is the same key that I have mentioned in section 5.2. This is the key used by the ACS to sign a set of claims for a particular scope. This is the same key using which the service generates the local HMAC to verify the authenticity of the claims/client. - The next step is to create the 'Scope'. Right click on the 'Scopes' and click 'create'. Fill in the below mentioned details. In your case, the 'Applies To' field should be URL of the resource/service that we are protecting using the ACS. Select the token policy in the drop down that we created in our previous step. Click 'OK'.
- Now we need to create rules. Expand the 'Scopes' and 'my-scope' section. You should see the 'Rules' node as follows:
- Now, right click on the 'Rules' node and click 'create'. Enter the below mentioned details.
The above entries mean that if a client sends the Issuer details as input claim, he should receive the mentioned output claims. Click 'OK'. - Now, all our details required for the ACS are in place. We can verify whether the claims that we have entered are as per our requirement. To do the same, click on the 'Claim Mapper' icon (icon on the immediate right of the 'Management Key' textbox). We get the following screen.
Select the mentioned values as shown below:
Click on 'Add Input Claim' button. The immediate textbox should get populated with the text 'Type:Issuer, Value:my-issuer'. Now click the 'Map Claims' button. The Output Claims text box should get populated with the appropriate values that we had defined in step 7. The screen should look as follows:
This is used to verify what values of the Output claims can be received from the ACS, if the entered Input claims are sent.
Now, after the verification is done, we need to save the details back to the cloud. Click on the 'Save to Cloud' icon ('floppy disk and cloud' icon). You should get the below mentioned pop up:
With the above steps, we have created a Service Namespace as well as the rules for our Service. Now the last step is to write a client code to fetch these claims from the ACS and send the same to our RESTful service.
Sample client code snippet:
As described in the diagram in section 6, the client first needs to make a request to the ACS by sending it the input claims. The ACS verifies the client and sends back the SWT. The second step is to invoke the RESTful service by sending it the SWT along with the request and receives the response.
The sample code is primarily divided into three small methods. The first method is the driver method. The second is the method responsible to fetch the SWT from the ACS. And the third method is used to invoke a RESTful service by sending it the SWT.
(I have used REST starter kit for writing the client code. The same can be downloaded. Explanation regarding usage of the kit is out of scope. However, the code is very simple and self explanatory. Also, any other library used for the http functions can be used for working with ACS.)
- The driver method:
The client project is a simple console app. The 'Main' method is the driver
method. It invokes the method '' to fetch the SWT from the ACS and then
invokes the method '' to invoke the desired RESTful service.
- GetToken method:
GetToken method has four input parameters. The description is as follows:
-
baseaddress: Address of the ACS. It is of the following format:
https://yournamspace.accesscontrol.windows.net
As per the example, in my case (Section 8.a), it would be:
https://saurabhvartak.accesscontrol.windows.net
-
wrap_name: It is the input claim value. In my case, it is 'my-issuer'.
(Section 8.b.7)
-
wrap_password: It is the 'my-issuer' key that we obtain in section 8.b.3.
Current key should be mentioned.
-
wrap_scope: It is the URL of the RESTful service/resource that we want to
protect using ACS (section 8.b.5 – the URL mentioned in the 'Applies To'
textbox)
In this method, we first create an HttpClient object with the base address
of the ACS.
We then form-urlencode the issuer name, password and the scope for which we
seek claims.
Later, we do an HTTP POST to the ACS with the above payload and read the
response and then extract the token (from the response) and send it back to
the calling program.
-
InvokeService method:
InvokeService method has three parameters.
-
token: the SWT that needs to be sent to the service.
-
param1 & param2: parameters that are to be sent to the service (specific
to my service. You folks can have a different set of parameters based on
your RESTful Service)
In this method, we first create the HttpClient object pointing to our
service.
Next, we construct the http Authorization header using the SWT that has been
passed to the method.
Later, we invoke the service and then read the service response.
With this, we have created a very simple client app, which requests a token
from the ACS and sends the same to the desired RESTful service. I shall deal
with the RESTful service in a follow up article.
However, you folks can refer to the 'ASPNET String Reverser' app that ships
with the SDK and create your own RESTful service. The 'ASPNET String
Reverser' app has a 'TokenValidator' class that reads a SWT and validates
it.
Happy programming.
References: