This sample demonstrates how to use the Active Directory Authentication Library (ADAL)
package to add user authentication capabilities to a WPF client. Furthermore,
it demonstrates how to authenticate calls to a Web API REST service by
leveraging the JSON Web Token Handler for Microsoft .Net Framework 4.5 (JWT
ADAL is a library, built on .Net 4.0, offering a simple programming model for Windows
Azure Active Directory (AAD) in client applications. Its main purpose is to
help developers easily obtain access tokens from Windows Azure Active
Directory, to be used for requesting access to protected resources such as REST
The JSON Web Token Handler for Microsoft .Net Framework (JWT handler) is a library built on
.NET 4.5 which adds the JSON Web token format as a first-class citizen in the
.NET programming model. The JWT handler can be used both within the WIF
pipeline, to secure existing Web sites and services with JWT tokens in addition
to the formats supported out of the box (such as SAML1.1 and SAML2). The JWT
handler can also be used standalone, with no direct dependencies on WIF
Running the Sample
Before running this sample, you will need to create an Azure Active Directory tenant and register the client and service in the sample with Azure AD and update the sample with your tenant information.
2. Register the client and service applications in AAD and update the sample
in to https://manage.windowsazure.com.
on Active Directory in the left hand pane.
- Click your directory.
- Click on Applications.
- Add Service application.
3. The sample is configured to run the
TodoListService in IIS Express on https. In order to get the sample working,
please copy the localhost certificate with friendly name = “IIS Express
Development Certificate” from Local Computer -> My store to Trusted Root
store, otherwise the calls to TodoListService made by ADAL (during 401
discovery) and TodoListClient fail with the reason that the https certificate
To run this sample, hit F5. The solution is configured to start multiple projects and will
take care to put all the right parts in motion.
You will get a 401 exception on the call to uthenticationParameters.CreateFromResourceUrl() which is expected since the client is doing 401 discovery by making a call to the TodoListService without an access token. Press F5 to continue.
In order to see
the scenario in action, enter a value in the textbox and click the “Add item”
button in the TodoListManager UI. Given that calling the corresponding service requires presenting a security token, the application will prompt you with a sign in page. Sign in as a user of your AAD domain.
Now that we have
a token, you will see that subsequent calls to the service will no longer
trigger an authentication prompt as the token is cached, unless the cache is cleared by clicking the Clear Cache button. The sample is configured with a custom cache, CredManCache.cs under TodoListClient. The CredManCache uses credential manager to store the AuthenticationResult objects that contain access token, refresh token, user id etc.
To clear the token cache, click the Clear Cache button which also clears the items in the
Todo items list. When you add an item again, you will be prompted with a sign in page.
When you want to stop debugging, hit the Stop button in Visual Studio.
Let’s take a quick look at the structure of the solution. If you want more detailed
information, please refer to the comments in the code.
A .Net 4.5 MVC4 WebAPI project implementing a simple REST façade on top of a collection of todo items. It utilizes the functionality in the JWT handler package.
A .Net 4.0 WPF project implementing a simple client which consumes the API exposed by TodoListService. TodoListClient can be used for adding new todo items and display the ones assigned to the signed in user. It utilizes the functionality in the ADAL package to display the Browser dialog for authenticating and getting a JWT token from AAD/ADFS.
ADAL is provided in the “Azure Directory Authentication Library” NuGet package and JWTSecurityTokenHandler in the “JSON Web Token Handler for Microsoft .Net Framework 4.5” NuGet package. Notice the assemblies “Microsoft.IdentityModel.Clients.ActiveDirectory” and “Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms” under the references node in the Solution Explorer in Visual Studio for TodoListClient project and “System.IdentityModel.Tokens” in the TodoListService project.
Let’s start from the client side of the solution. Open the TodoListClient project and
look at the MainWindow.xaml.cs
You will also see that we have setup some application-level members, AuthenticationContext , a “proxy” for your tenant. On initialization the AuthenticationContext is set to the authority specified in the authority variable and the custom cache, CredManCache.
In the MainWindow() you will see that the client calls AuthenticationParameters.CreateFromResourceUrl() to do a 401 discovery and get the values of authority and resourceAppIdUri.
When the Add item button is clicked the GetAuthorizationHeader() method is called, which calls AcquireToken() method in ADAL.Net to get an AuthenticationResult containing an access token and then returns a http authorization header with the access token obtained from ADAL.
You can see how the JWT token is utilized in the GetResponseFromService() method. Here the accessToken is put in the Authorization header of the HTTP Request sent to the TodoListService.
Finally on the Client side, take a look at CredManCache.cs. You will see that CredManCache is a dictionary of TokenCacheKey and string pair. TokenCacheKey contains fields like authority, clientId, resource etc. CredManCache encodes the TokenCacheKey into a string to store in CredMan and decodes the key back to TokenCacheKey while reading the entries. CacheHelper.cs has the logic to encode and decode the keys of type TokenCacheKey. The values in the dictionary are string representation of AuthenticationResult.
Since the cache
is a dictionary, you can run Linq queries on it, for example, to find all the
tokens obtained from a specific authority or find all the tokens of a specific user etc.
Moving on to the
service side: open the TodoListService project and examine
Global.asax.cs. The most interesting class here is
TokenValidationHandler, an implementation of DelegatingHandler.
TokenValidationHandler‘s purpose is
to process request messages before they reach the application code and enforce authentication requirements. The method
TryRetrieveToken inspects incoming http requests to verify if the authorization header contains
an OAuth2 header with a bearer token. If a bearer token is not found, the
request is not authorized and an unauthorized status code along with the
authorization url and resource Id is sent back to the Client. If the header contains a bearer token, it is validated through the JWT handler. A TokenValidationParameters object is created to set the expected properties, issuer, audience and signing token, on the token. The method ValidateToken() is then called to validate the token and, upon successful validation, a new ClaimsPrincipal instance is set as the Principal of the current thread and as the Current user in HttpContext.
The sample solution is designed to run from your local machine; you can explore the scenario without having a Windows Azure subscription, and in fact you can choose to use ADAL to connect to Windows Azure Active Directory regardless of where you will run your services.
That said, here are detailed instructions you can follow if you want to deploy the TodoListService to Windows Azure.
The steps below assume that you are using the April 2013 release of the Windows Azure
SDK. Also note that to debug you will need to run VS in administrator mode.
3. To test on the local simulation environment: open MainWindow.xaml.cs in the TodoListClient project and change the resourceBaseAddress value to http://127.0.0.1:81/. You will also have to relax the validation on resourceAppIdUri, which would not work now. So, move the “resourceAppIdUri = parameters.Resource;” statement out of the if block and comment out the if and else statement in MainWindow().
4.To publish select Publish on the TodoListService.Azure project. Select the Cloud Service where you would like to deploy to and choose Publish.
2. Once the deployment took place: before launching the debugger, change your startup projects settings so only the following projects are enabled: