NOTE: This sample is outdated. The technology, methods, and/or user interface instructions used in this sample are still supported, but have been succeeded by newer features.  The scenario addressed by this sample is accomplished using the latest technology in NativeClient-DotNet.

Authentication via Browser Dialog - Readme

Overview

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
handler).

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
services.


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
configuration.

 

Prerequisites

 


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.

 

  1. If you don’t have your own Windows Azure AD tenant, please follow the “Create
    a New Directory Tenant and Add a User”
    section in Windows Store app walk

    through to create one.

 

       2. Register the client and service applications in AAD and update the sample

 

 

 

Figure 1

 




Figure 2

 

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
is invalid.

 

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.


Details


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.

 

TodoListService:

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.


TodoListClient:

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.ActiveDirectoryand “Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms” under the references node in the Solution Explorer in Visual Studio for TodoListClient project and “System.IdentityModel.Tokensin the TodoListService project.


Let’s start from the client side of the solution. Open the TodoListClient project and
look at the MainWindow.xaml.cs

 

  1. authority
    refers to the AAD tenant in https://login.windows.net/<tenant_name_or_ID> format, for example, “https://login.windows.net/treyresearch.onmicrosoft.com. It could be set to https://login.windows.net/common to defer figuring out the domain till users sign in.  Here it is set to string.Empty, as the client is going to get the value from the TodoListService.
  2. clientId
    is a unique identifier for the TodoListClient application which is registered
    in AAD for your tenant (see Figure 2). 
  3. redirectUri
    is a URI of the client App registered in AAD (see Figure 2).
  4. resourceAppIDUri
    is the identifier that will be used by TodoListClient application to identify the target service resource  when requesting authorization for the service from Windows Azure AD (see Figure 1).  The value of resourceAppIdUri is also going to be obtained from the TodoListService in addition to authority.


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.


Deploying the TodoListService to Windows Azure


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.

 

  1. In the Solution Explorer, right click
    on the TodoListService project and choose Add Windows Azure Cloud
    Service Project
    .  This will create a new project called TodoListService.Azure.
  2. Make sure that multiple startup
    projects are still enabled. The following should be marked as startup projects
    now:

 

 

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.

    1. Once published open MainWindow.xaml.cs in the TodoListClient project and change the resourceBaseAddress value to the URL of the published service.

     

         2. Once the deployment took place: before launching the debugger, change your   startup projects settings so only the following projects are enabled:

 


Security Considerations

 

  1. When a custom token cache is plugged
    into ADAL, make sure that the entries in the cache are encrypted so that they
    are secure.
  2. Note that the browser dialog that is
    used for the authentication flow in ADAL does not have an address bar.
  3. The JWT Tokens issued by AAD are bearer
    tokens and may not be encrypted and hence must be sent to the service on a
    secure channel like https in order to prevent information disclosure, spoofing
    and other security attacks.
  4. The exceptions thrown by the JWT handler
    could contain sensitive information and it is up to the applications using it
    to make sure that this sensitive information is not sent to the Client.
  5. JWT handler could be configured to
    skip audience verification and Issuer verification. The security implications
    of turning off these checks should be understood.
  6. The
    JWT tokens issued by AAD are credentials (alike to passwords) and include
    information about users which may be considered sensitive information.  The JWT token handler does not log tokens.  Applications that log tokens should protect
    the log data appropriately to prevent information disclosure, spoofing, and
    other security attacks.