Introduction to Windows Azure Active Directory
Overview
In this hands-on lab you will learn how to use Windows Azure Active Directory for implementing web single sign-on in an ASP.NET application. The instructions will focus on taking advantage of the directory tenant associated with your Windows Azure subscription, as that constitutes the obvious choice of identity providers for Line of Business (LoB) applications in your own organization. This lab will show you how to provision the same application in a Windows Azure AD tenant, and how to configure the application's sign-on settings to connect to that tenant. At the end of the walkthrough, you will have a functioning web application fully configured for organizational single sign-on.
Benefits of Active Directory
- It makes the task of network administration simpler by maintaining a central repository of information.
- It provides a single destination to look out for information.
- It provides highly secured access to data through the usage of security policies.
- Thereby it improves the management of security data and workflows.
- Easily scalable. Supports millions of objects in a single domain.
- Unified access to resources by supporting a uniform naming convention.
Key Facts about Single Sign-On
In concrete terms This means that the application will be configured to redirect unauthenticated requests to the IdP, according to some sign-on protocol such as SAML-P, WS-Federation or OpenID Connect. (idP means identity provider)
Windows Azure Active Directory makes it easy to authenticate and authorize users.
You don't need to spend much time worrying about the vast landscape of changing security standards.
Windows Azure Active Directory is a cloud-based service that provides an easy way of authenticating and authorizing users to gain access to your web applications and services while allowing the features of authentication and authorization to be factored out of your code.
Because it is a service, all that security plumbing code is something you DO NOT NEED to worry about.
Windows Azure Active Directory supports integrated Single Sign On and centralized authorization into your web applications
Users hate having to log on mutliple times. If you want to retain your users, you need to allow them to just login once.
Windows Azure Active Directory provides out-of-the-box support for Active Directory Federation Services (AD FS) 2.0
Great integration story with on-premise corporate users. Windows Azure Active Directory relies on Standards-based identity providers Web identities include Windows Live ID, Google, Yahoo! and Facebook
SAML
SAML Tokens, WS-Federation, https
SAML is an XML-based open standard data format for exchanging authentication and authorization data between parties, in particular, between an identity provider and a service provider.
- SAML is a product of the OASIS Security Services Technical Committee
SOAP
SOAP on the decline relative to REST-based technologies
SOAP is for exchanging structured information in the implementation of Web Services in computer networks.
It relies on XML Information Set for its message format, and usually relies on other Application Layer protocols, most notably Hypertext Transfer Protocol (HTTP) or Simple Mail Transfer Protocol (SMTP), for message negotiation and transmission.
What is WS-Federation?
WS-Federation is a WS-* specification and OASIS standard
Tries to tackle the security challenges in web applications and web services in a variety of trust relationships.
WS-Federation supports SOAP clients and web services. REST is not supported.
WS-Federation provides a common model for performing Federated Identity operations for both web services and browser-based applications.
WS-Federation builds upon the Security Token Service model
WS-Security, WS-Trust, and WS-SecurityPolicy provide a basic model for federation between Identity Providers and Relying Parties
WS-Federation are claims-based.
Claims are just dictionaries inside of a SAML token where key value pairs represent the attributes of a user
Developers can iterate through dictionary to see attributes of a user’s identity to determine what kind of claims we want to authorize
These claims are also called assertions. WS-Federation strives for richer trust relationships
It wants to join together HTTP with STS and WS-Trust to allow resources in one realm get identities (and related attributes) that are managed and maintained in another realm.
You can imagine scenarios where WS-Federation is needed, such as protecting patient records from unauthorized users when these patient records are traveling among multiple health providers.
Federation makes sense in a supply chain scenario where a factory needs just-in-time inventory levels from distributors or retailers (and in reverse).
What is single sign-on?
Single sign-on (SSO) is a property of access control of multiple related, but independent software systems.
- With single sign-on a user logs in once and gains access to all systems without being prompted to log in again at each of them.
Differences between Visual Studio 2012 and 2013
Here there are some comments on the main differences according to this post by Vittorio.
Re-entrancy. Right now VS2013 can configure authentication only at project creation time. Re-entrancy is being considered as a feature for a future update
ACS support. As detailed in https://blogs.technet.com/b/ad/archive/2013/06/22/azure-active-directory-is-the-future-of-acs.aspx, ACS will not receive further investments hence VS2013 will not support it directly.
- As equivalent ACS functionality appears in Windows Azure AD, VS2013 will expose it accordingly - Local STS.
- Support for Local STS didn't make it in VS2013.
- There are community driven alternatives (see https://brockallen.com/2013/10/22/announcing-thinktecture-embeddedsts-a-simple-local-sts-for-asp-net-applications/).
Objectives
In this hands-on lab, you will learn how to:
- Create a new Windows Azure Active Directory tenant.
- Provision an MVC application in the AD tenant.
- Configure application's sign-on and sign-out settings.
- Query Active Directory data using Graph AD API.
Prerequisites
The following is required to complete this hands-on lab:
- Windows Azure subscription - sign up for a free trial
- You must use Visual Studio 2012 Professional or Visual Studio 2012 Ultimate
- The tooling isn't available in Visual Studio 2013 as of 3/2/2014.
- Identity and Access Tools for Visual Studio 2012
- WCF Data Services 5.3 Tools
Setup
Everything you need to complete this lab is here. I am running Windows 8 and Visual Studio 2012. I have also installed the latest Azure SDK (2.2).
There were a few adjustments that I had to make.
For those of you who are interested in helping with the Azure dev camps, here is the agenda that we are advertising: https://1drv.ms/1dilbFb
The overall schedule by city and related content can be found. https://www.devcamps.ms/windowsazure
The installer for all the content can be found here: https://www.contentinstaller.net/Install/ContentGroup/WAPCamps
This lab is the last of three labs that is being given during Microsoft national Azure Dev Camp series.
Exercises
This hands-on lab includes the following exercises:
- Adding Sign-On to Your Web Application Using Windows Azure Active Directory
- Using the Graph API to Query Windows Azure Active Directory
Note: Each exercise is accompanied by a starting solution. These solutions are missing some code sections that are completed through each exercise and therefore will not necessarily work if running them directly. Inside each exercise you will also find an end folder where you find the resulting solution you should obtain after completing the exercises. You can use this solution as a guide if you need additional help working through the exercises.
Estimated time to complete this lab: 45 minutes.
Note: When you first start Visual Studio, you must select one of the predefined settings collections. Every predefined collection is designed to match a particular development style and determines window layouts, editor behavior, IntelliSense code snippets, and dialog box options. The procedures in this lab describe the actions necessary to accomplish a given task in Visual Studio when using the General Development Settings collection. If you choose a different settings collection for your development environment, there may be differences in these procedures that you need to take into account.
Exercise 1: Adding Sign-On to Your Web Application Using Windows Azure Active Directory
In the first exercise you will learn how to provision a new Windows Azure AD tenant within your Windows azure subscription, and how to operate the Windows Azure AD Management Portal features to register an application.
Task 1 - Creating a New Directory Tenant
In this task, you will provision a new Windows Azure Active Directory Tenant from the Management Portal.
Navigate to https://manage.windowsazure.com using a web browser and sign in using the Microsoft Account associated with your Windows Azure account.
Select Active Directory from the left pane.
Accessing Windows Azure Active Directory
- Click the Add button from the bottom toolbar.
Adding a new Active Directory Tenant
- Enter a Domain Name (must be unique), select a Region and type an Organization Name. Click the check button to continue.
Filling Active Directory Information
Note: This dialog gathers essential information needed to create a directory tenant for you.
Organization Name: This field is required, and its value will be used as a moniker whenever there's the need to display the company name.
Country or Region: The value selected in this dropdown will determine where your tenant will be created. Given that the directory will store sensitive information, please do take into account the normative about privacy of the country in which your company operates.
Domain Name: This field represents a critical piece of information: it is the part of the directory tenant domain name that is specific to your tenant, what distinguishes it from every other directory tenant.
At creation, every directory tenant is identified by a domain of the form .onmicrosoft.com. That domain is used in the UPN of all the directory users and in general wherever it is necessary to identify your directory tenant. After creation it is possible to register additional domains that you own. For more information, see domain management.
The Domain Name must be unique: the UI validation logic will help you to pick a unique value. It is recommended that you choose a handle which refers to your company, as that will help users and partners as they interact with the directory tenant.
- Wait until the Active Directory is created (its status should display Active).
Note: When a directory tenant is created, it is configured to store users and credentials in the cloud. If you want to integrate your directory tenant with your on-premises deployment of Windows Server Active Directory, you can find detailed instructions here.
- Click on the newly created directory entry to display the user management UI. The directory tenant is initially empty, except for the Microsoft Account administering the Windows Azure subscription in which the new tenant was created.
Active Directory User List
- Now you will add a new user to the directory. Click the Add User button in the bottom bar.
Adding a new user to Active Directory
- In the dialog box, keep the default option of New user in your organization and type a username (e.g.: newusername). Click Next to continue.
Filling new user details
- Enter the user profile data. Keep the Role option of User.
Filling user profile information
You will click to create a temporary password.
The Management Portal generates a temporary password, which will have to be used at the time of the first login. At that time the user will be forced to change password. Click the create button. Take note of the temporary password, as you will need it in the following tasks. Click the check button to create the user.
Creating a temporary password
At this point we have everything we need for providing an authentication authority in our web SSO scenario: a directory tenant and a valid user in it.
- Note that the new user can be seen at the portal.
Adding a new user
Note You will use newusername@devcampdomain.onmicrosoft.com to login.
Task 2 - Creating and Registering an MVC App in Active Directory Tenant
In this task, you will create a new MVC Application using Visual Studio 2012 and you will register it in the Active Directory tenant you created in the previous task.
Open Microsoft Visual Studio 2012 as administrator by right-clicking the Microsoft Visual Studio 2012 shortcut and choosing Run as administrator.
From the File menu, choose New Project.
In the New Project dialog, expand Visual C# in the Installed list and select Web. Choose the ASP.NET MVC 4 Web Application template, set the Name of the project to ExpenseReport and set a location for the solution. Click OK to create the project.
Creating a new MVC 4 Application in Visual Studio 2012
- In the New ASP.NET MVC 4 Project window, select Intranet Application, make sure the view engine is set to Razor, and then click OK.
Selecting MVC 4 Intranet Application template
- Select your project in the Solution Explorer, then in the Properties pane, switch SSL Enabled to True. Copy the SSL URL.
Note The Virtual Directories used by IISExpress are defined here: C:\Users[user nane]\Documents\IISExpress\config
The file is applicationhost.config
Switching Web App to use SSL
Note: Visual Studio configures your application to serve content through HTTP. However, that would not be suitable for establishing secure sessions, given that it would leave communications unprotected and allow potential attackers to steal cookies and tokens. This is not mandatory during the development phase, as Windows Azure will not strictly enforce use of HTTPS. It is always a good practice though.
What is SSL?
SSL is a protocol for encrypting information over the Internet. SSL uses the public-and-private key encryption system from RSA, which also includes the use of a digital certificate.
- How SSL works.
- The browser reserver identify itself.
- The server sends the browser a copy of its SSL Certificate.
- The browser can decide if it trusts the SSL Certificate.
- If the browser does, it sends a message to the server.
- The server sends back a digitally signed acknowledgement to start an SSL encrypted session.
- Encrypted data is shared between the browser and the server and https appears.
- Right-click the project and choose Properties. Choose the Web tab on the left, scroll down to the Use Local IIS Web server option and paste the HTTPS URL in the Project Url field. Save settings (CTRL+S) and close the property tab.
Expense Report Properties using Visual Studio 2012
- Minimize Visual Studio and go back to the Management Portal. Go to your Active Directory tenant and click Applications. Click the Add an app link.
Adding an Application to Active Directory
Note: No application can take advantage of Windows Azure AD if they are not registered: this is both for security reasons (only apps that are approved by the administrator should be allowed) and practical considerations (interaction with Windows Azure AD entails the use of specific open protocols, which in turn require the knowledge of key parameters describing the app).
- Select the first option, Add an application my organization is developing
Adding an app
- Enter the name of your application (e.g.: Expense Report) and select Web Application and/or web api
Specifying the name and application type
- Enter the SSL URL from the MVC Application in both fields APP URL and APP ID URI. Click the check button to complete the application registration.
Entering Application URL
Note: In this screen the Windows Azure Management Portal gathers important coordinates which the service needs to drive the sign-in protocol flow.
APP URL: This parameter represents the address of your web application. Windows Azure AD needs to know your application's address so that, after a user successfully authenticated on Windows Azure AD's pages, it can redirect the flow back to your application.
APP ID URI: this parameter represents the identifier of your web application. Windows Azure AD uses this value at sign-on time, to determine that the authentication request is meant to enable a user to access this particular application - among all the ones registered - so that the correct settings can be applied. The APP ID URI must be unique within the directory tenant. A good default value for it is the APP URL value itself, however with that strategy the uniqueness constraint is not always easy to respect: developing the app on local hosting environments such as IIS Express and the Windows Azure Fabric Emulator tend to produce a restricted range of addresses that will be reused by multiple developers or even multiple projects from the same developer.
- Finishing the application properties. Indicate the type of access that the application needs in Windows Azure AD. You can select option 3, single sign-on, read and write directory data. Why not, this is a test account.
Specifying the App URL and the App ID URI
- You successfully registered the application within your Active Directory tenant. In the application dashboard, copy the Federation Metadata Document URL from the Enable single sign-on with Windows Azure AD section. You will use it in the following tasks. You will go back to Visual Studio and use the information seen below.
Copying Federation Metadata URL
Task 3 - Connecting the application to Windows Azure Active Directory
In this task, you will run the Identity and Access configuration to set up your application with Windows Azure Active Directory. Visual Studio 2012 offers point and click tools which can help you to configure applications to use WS-Federation for web sign-on: you can use the tool's UI to provide few key information about the authority you want to trust for authentication, and the tool will emit the corresponding configuration entries.
Identity and Access is not automatically built into Visual Studio. But it is easy to add.
- Navigate to the following Url:
https://visualstudiogallery.msdn.microsoft.com/e21bf653-dfe1-4d81-b3d3-795cb104066e
Visual Studio Extension
- Click Open.
Installing the extension
- Set project properties as follows. Right mouse click the project and choose Properties.
Note The Identity and Access menu will not appear until you set the Framework version to 4.5.
Getting the Identity and Access menu to appear
- Go back to Visual Studio, right-click the ExpenseReport project node and select Identity and Access... .
Opening Identity and Access tools
- The tool lists various authority types you can use to outsource authentication. In this specific case, you will select Business Identity Provider. Paste the Federation Metadata URL you copied in the previous task in the Enter the path to the STS metadata document field. The APP ID URI will be already filled in the dialog. Press OK to continue.
Configuring the Business Identity Provider
Note: As you paste in the textbox the path to the metadata document, the tool will display a warning about a certificate being invalid. That is due to the fact that the metadata document is signed with a self-signed certificate, and should not be cause for concern.
- You may also take a look in web.config. You can see that it has been updated. This is informational only. You do not need to modify this file.
XML
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=169433
-->
<!-- OMITTED FOR CLARITY -->
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="https://localhost:44300/" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="https://sts.windows.net/c7489633-0f79-4db6-b12b-404d527897bd/">
<keys>
<add thumbprint="92B88asdfasdfasdf" />
<add thumbprint="3sdagfasdfasdf" />
</keys>
<validIssuers>
<add name="https://sts.windows.net/c7489633-0f79-4db6-b12b-404d527897bd/" />
</validIssuers>
</authority>
</issuerNameRegistry>
<!--certificationValidationMode set to "None" by the the Identity and Access Tool for Visual Studio. For development purposes.-->
<certificateValidation certificateValidationMode="None" />
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" />
<wsFederation passiveRedirectEnabled="true" issuer="https://login.windows.net/c7489633-0f79-4db6-b12b-404d527897bd/wsfed" realm="https://localhost:44300/" requireHttps="false" />
</federationConfiguration>
</system.identityModel.services>
</configuration>
The tool auto generates entries in the Web.config file. This is all you need for taking advantage of Windows Azure AD for Web sign-on. Now, you will display the authenticated user information in the Home page of the application. Open HomeController.cs under the Controllers folder.
Add the following directive at the top of the class.
C#
using System.Security.Claims;
Replace the Index method contents with the following code.
(Code Snippet - Introduction to Windows Azure AD - Ex1 Querying ClaimsPrincipal)
C#
public ActionResult Index() { ClaimsPrincipal cp = ClaimsPrincipal.Current; string fullname = string.Format("{0} {1}", cp.FindFirst(ClaimTypes.GivenName).Value, cp.FindFirst(ClaimTypes.Surname).Value); ViewBag.Message = string.Format("Dear {0}, welcome to the Expense Note App", fullname); return View(); }
Note: Starting from .NET 4.5, every identity in .NET is represented with a ClaimsPrincipal. In this case, the current ClaimsPrincipal has been constructed during the validation of an authentication token generated by Windows Azure AD and presented by the user at sign-on time.
Before running, you need to prevent a runtime error. In the next step you will prevent this error from occurring.
A potential runtime error
- In the Application_Start event, you want to use to uniquely identify the user. You do this by setting the AntiForgeryConfig.UniqueClaimTypeIdentifier property. The code needs to add the line:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
C#
namespace ExpenseReport
{
using System.Security.Claims;
using System.Web.Helpers;
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit https://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
// Add this line
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
}
Run the application by pressing F5.
A security certificate warning will appear in your browser. This is a expected behavior, click Continue to this website (not recommended) .
Browser displaying Security Certificate Warning
- The URL address bar is replaced by the one of the authority, and the user is prompted to authenticate via the Windows Azure AD UI. Use the credentials from the user you created in a previous task.
Logging in to the Application
- You might recall that when you created the user in your Windows Azure AD tenant the Management Portal assigned to it a temporary password. You have to authenticate using that password. However, given that such password was meant to be temporary, during this very first sign-in operation you will be asked to choose a proper user password before being able to move forward with the authentication flow. Once you'll be done with that, the normal sign-in flow to the app will be restored.
Typing New User Password
- At the Home page, you can notice the username displayed at the top right of the page and the user's first and last name displayed in the center of the page. There are a few things to notice here:
- The certificate error at the top is normal, since we are not using a certificate from a trusted certificate authority.
- The second red box shows that the MVC app is tracking identity.
- The third red box simply shows that the username is available inside of the application, not just the login email.
Displaying User Name in Home Page
At this point your application has all you need to demonstrate web sign-on with Windows Azure AD, however it is not complete yet. There are at least other two important features you will want to add: support for sign out and automatic refresh of the authority's protocol coordinates.
Task 4 - Adding Sign Out to the MVC App
In this task, you will add a Sign Out Controller to the MVC app. The web sign-on protocols in use today often include provisions for performing distributed sign out operations. Those are flows in which not only the current application cancels its current user's session, but it also reaches out to the authority to signal that a sign out command should be propagated to all the other applications' sessions that might have been established by the same authority.
- In Visual Studio, right-click the Controllers folder, select Add and then Controller. Name it SignOutController, choose Empty MVC Controller as Template and click Add.
Adding a SignOutController to the project
Right-click the ExpenseReport project node and select Add Reference. Select the Assemblies node from the left pane, type system.identitymodel.services in the Search Assemblies field, and select the corresponding assembly from the main list. Press OK.
Open SignOutController.cs file and add the following directives.
C#
using System.IdentityModel.Services;
using System.IdentityModel.Services.Configuration;
- Replace the contents of the SignOutController class with the following highlighted code.
(Code Snippet - Introduction to Windows Azure AD - Ex1 SignOutController)
C#
public class SignOutControllerController : Controller
{
public ActionResult Index()
{
return View("SignOut");
}
public void SignOut()
{
WsFederationConfiguration fc =
FederatedAuthentication.FederationConfiguration.WsFederationConfiguration;
string request = System.Web.HttpContext.Current.Request.Url.ToString();
string wreply = request.Substring(0, request.Length - 7);
SignOutRequestMessage soMessage =
new SignOutRequestMessage(new Uri(fc.Issuer), wreply);
soMessage.SetParameter("wtrealm", fc.Realm);
FederatedAuthentication.SessionAuthenticationModule.SignOut();
Response.Redirect(soMessage.WriteQueryString());
}
}
Note: The sample application demonstrated here does not do much, but your real applications might allocate resources during a user's session. If that is the case, you can take advantage of the SAM's events SigningOut and SignedOut by adding corresponding event handlers in the Global.asax file to clean up whatever resources should be disposed upon closing a session.
Right-click on the Views folder, select Add and then New Folder. Name it SignOut.
Right-click the newly created SignOut folder, select Add and then View. Name it SignOut and leave the rest of the fields with the default values. Click Add.
Adding the SignOut View
- Replace the placeholder <h2> tag with the following.
CSHTML
<h2>You have successfully signed out</h2>
- You configured the application to handle authentication via blanket redirects. That means that, if you try to access this View after a successful sign out you will be immediately redirected to Windows Azure AD to sign in again! To avoid that behavior, you can use the <location> element in the web.config to create one exception to the authentication policy. Open Web.config, locate the first occurrence of the <location> tag and paste the following block just below it.
(Code Snippet - Introduction to Windows Azure AD - Ex1 Location element)
XML
<configuration>
...
<location path="FederationMetadata">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
<location path="SignOut">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
</configuration>
Open the _Layout.cshtml file located under Views | Shared folder.
Locate the <section> with id login and replace its contents with the following.
(Code Snippet - Introduction to Windows Azure AD - Ex1 Layout View)
CSHTML
<section id="login">
@if (Request.IsAuthenticated)
{
<text> Hello, <span class="username">@User.Identity.Name</span>!
@Html.ActionLink("Signout","SignOut", "SignOut")</text>
}
else {
<text> You are not authenticated </text>
}
</section>
Press F5 to run the application. Log in the application using the AD user credentials.
In the Home page, click the Signout button located at the top right of the page.
You will be signed out and you will be presented with the SignOut view.
Signed Out View
Task 5 - Adding Automatic Metadata Refresh
The Identity and Access Tool configured your application to accept tokens coming from your Windows Azure AD tenant of choice. In order to do so, it cached in the Web.config the necessary protocol coordinates for connecting to the intended Windows Azure AD endpoints. It is common security practice to regularly renew cryptographic keys, and Windows Azure AD signing keys are no exception: at fixed time intervals the old keys will be retired, and new ones will take their place in the issuer's signing logic and in your tenant's metadata document.
To minimize downtime, it is a good idea to add self-healing logic directly in the application so that you can consume the metadata document programmatically and react to key rolling without the need of operator's intervention.
In Visual Studio, right-click the ExpenseReport project node and select Add Reference. Select the Assemblies node from the left pane and type System.IdentityModel in the search box. Check the assembly and click OK.
Open Global.asax file and add the following directives.
C#
using System.Configuration;
using System.IdentityModel.Tokens;
- Add the following method at the bottom of the class.
(Code Snippet - Introduction to Windows Azure AD - Ex1 Refresh Validation Settings)
C#
protected void RefreshValidationSettings()
{
string configPath = AppDomain.CurrentDomain.BaseDirectory + "\\" + "Web.config";
string metadataAddress =
ConfigurationManager.AppSettings["ida:FederationMetadataLocation"];
ValidatingIssuerNameRegistry.WriteToConfig(metadataAddress, configPath);
}
Note: The ValidatingIssuerNameRegistry is the class used by the Identity and Access Tool to record information about which authorities are trusted, and what keys should be used to verify the tokens they issue. WriteToConfig is a static method that reads the issuer settings from a metadata document (in this case retrieved from config, where it was stored in the tool's first run, by the method's second line) and uses it to create or update the corresponding config section of the file at the path specified (constructed from the current AppDomain in the first line of the method).
- Insert a call to the RefreshValidationSettings method at the end of the Application_Start method.
C#
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
RefreshValidationSettings();
}
Note: Calling RefreshValidationSettings from Application_Start guarantees that the Web.config will be modified in a safe time, whereas if you would do that later in the app's lifecycle you'd risk triggering a refresh.
Exercise 2: Using the Graph API to Query Windows Azure Active Directory
This exercise builds upon the previous one and will show how to add capability to read directory data using the Windows Azure AD Graph API. The Graph API is a new RESTful API that allows applications to access customers' Windows Azure directory data.
Using the Windows Azure AD Graph, developers can execute create, read, update, and delete (CRUD) operations on Windows Azure AD objects such as users and groups.
Typical use cases include people pickers, validating a user’s security group membership, updating group membership, provisioning new users and groups, resetting users’ passwords, and validating a tenant or users’ licensing information.
Task 1 - Configuring Application Authorization and Authentication for the Graph API
In this task you will update the application configuration in the Management Portal to enable the MVC application to authenticate and be authorized to call the Graph API. With authorization, you configure your app permissions to allow read/write access to the directory. With authentication, you get an Application Key, which is your application's password and will be used to authenticate your application to the Graph API.
- Log on to the Windows Azure Management Portal, select Active Directory from the left pane and click the application name you created in the previous exercise.
Selecting Application Name
- Click Manage Access on the bottom toolbar.
Manage Access Button
- On the What do you want to do? screen, select Change the directory access for this app.
Changing the Directory Access for the App
- On the Directory access required by this app screen, select the radio button next to SINGLE SIGN-ON, READ DIRECTORY DATA, and then click the check button in the bottom right-hand corner of the screen to save your changes.
Selecting Directory Access for the App
Configuring Key for Read and Write
- Select the Configure key option under the CREATE A KEY section.
Configuring the Keys
- In the Configure page, under the Keys section, add a key by selecting the key's lifespan (default 1 year), and then click Save at the bottom of the screen. This will generate a key value that is your application's password and will be used in the application configuration.
Note: The key value is displayed after key creation, but cannot be retrieved later. Therefore, you should immediately copy the key value and store it in a secure place for your future reference. Also, your application can have multiple keys. For example, you may want one or more for testing and production.
Generating Key for Read and Write
Task 2 - Including Graph API Helper in MVC App
In this task you will add the Graph API Helper to your MVC app. This helper is a class project that includes a library and classes that facilitate authenticating to and calling the Graph API.
- Download the Graph API Helper project from https://go.microsoft.com/fwlink/?LinkID=290812.
Download Graph API Helper
If not already open, start Visual Studio 2012 Professional or Ultimate and continue with the solution obtained from the previous exercise. This task assumes you have completed the previous exercises and tasks.
To add the Graph API Helper to the single sign-on project, right-click the solution, click Add | Existing Project.
From the Add Existing Project dialog, navigate to the folder where you downloaded the Graph API Helper and open the Microsoft.WindowsAzure.ActiveDirectory.GraphHelper.csproj project file.
Opening GraphHelper.csproj
- Open the Web.config file of the ExpenseReport project. Add the following key values to the appSettings section. Make sure you update the [YOUR-CLIENT-ID] placeholder with the Client ID value obtained from the Configure tab of your application in the Windows Azure Management Portal and the [YOUR-APPLICATION-KEY-VALUE] placeholder with the key that you generated in the previous task.
XML
<appSettings>
<add key="ClientId" value="[YOUR-CLIENT-ID]"/>
<add key="Password" value="[YOUR-APPLICATION-KEY-VALUE]"/>
...
<appSettings>
Save the Web.config file after making the changes.
In the next steps, you will add and possibly update the Microsoft.Data.Edm, Microsoft.Data.OData and System.Spatial references from version 5.2.0 to version 5.3.0. From the ExpenseReport project, expand the References folder and delete the Microsoft.Data.Edm, Microsoft.Data.OData and System.Spatial references.
Note: This is necessary because the Graph API Helper is using a newer version (5.3.0) of those assemblies.
- You may need to download the correct version of Microsoft.Data.Edm, Microsoft.Data.OData and System.Spatial here: https://www.microsoft.com/en-us/download/details.aspx?id=36516. The older versions, specifically 5.3.0.0, is what is needed.
Downloading version 5.3.0.0 of WCF Data Servcies 5.0
- After running the install, files could be find in the GraphAPIHelper folder, **C:\\Users\[user name\]\\Documents\\Visual Studio 2012\\Projects\\ExpenseReport\\GraphAPIHelper\\WindowsAzure.AD.Graph.2013\_04\_05\\bin\\Debug**.
-
There are the latest files
[![enablegraph6](https://msdntnarchive.z22.web.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/13/13/metablogapi/5383.enablegraph6_thumb_1BCA43B2.png "enablegraph6")](https://msdntnarchive.z22.web.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/13/13/metablogapi/4035.enablegraph6_7EC194E9.png)
*Version 5.3.0.0 of the files*
-
Be sure to update both projects - instructions to follow.
[![enablegraph9](https://msdntnarchive.z22.web.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/13/13/metablogapi/3630.enablegraph9_thumb_1E97AAB8.png "enablegraph9")](https://msdntnarchive.z22.web.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/13/13/metablogapi/6864.enablegraph9_5B96BAE8.png)
*Updating references to version 5.3.3.0*
Right-click the References folder of the ExpenseReport project and click Add Reference.
On the Reference Manager dialog, click Extensions from the left menu, then select the Microsoft.Data.Edm, Microsoft.Data.OData, System.Spatial and the Microsoft.Data.Services.Client version 5.3.0.0 assemblies. You may need to browse to the folder mentioned previously.
Microsoft Data References
- In the same Reference Manager dialog, expand the Solution menu on the left and then select the checkbox for the Microsoft.WindowsAzure.ActiveDirectory.GraphHelper. Click OK to add the references.
Graph API Helper Reference
Task 3 - Displaying Active Directory Query Data
In this task you will update the HomeController of your MVC app to query the list of users from the Active Directory tenant using the Graph API Helper, and create a view to display the results.
- In the Solution Explorer, expand the Controllers folder of the ExpenseReport project and open the HomeController.cs. Add the following assemblies to the file and then save it.
(Code Snippet - Introduction to Windows Azure AD - Ex2 Home Controller References)
C#
using System.Configuration;
using System.Security.Claims;
using System.Data.Services.Client;
using Microsoft.WindowsAzure.ActiveDirectory;
using Microsoft.WindowsAzure.ActiveDirectory.GraphHelper;
- Add the following action method at the end of the HomeController class, which will retrieve the list of users from the Active Directory tenant using the Graph API Helper to obtain a JWT (JSON Web Token). This token is inserted in the Authorization header of subsequent requests from the Graph API.
(Code Snippet - Introduction to Windows Azure AD - Ex2 Users Action Method)
C#
public class HomeController : Controller
{
...
public ActionResult Users()
{
//get the tenantName
string tenantName = ClaimsPrincipal.Current.FindFirst("https://schemas.microsoft.com/identity/claims/tenantid").Value;
// retrieve the clientId and password values from the Web.config file. Accomplished in previous step.
string clientId = ConfigurationManager.AppSettings["ClientId"];
string password = ConfigurationManager.AppSettings["Password"];
// get a token using the helper
AADJWTToken token = DirectoryDataServiceAuthorizationHelper.GetAuthorizationToken(tenantName, clientId, password);
// initialize a graphService instance using the token acquired from previous step
DirectoryDataService graphService = new DirectoryDataService(tenantName, token);
// get Users
//
var users = graphService.users;
QueryOperationResponse<User> response;
response = users.Execute() as QueryOperationResponse<User>;
List<User> userList = response.ToList();
ViewBag.userList = userList;
// For subsequent Graph Calls, the existing token should be used.
// The following checks to see if the existing token is expired or about to expire in 2 mins
// if true, then get a new token and refresh the graphService
//
int tokenMins = 2;
if (token.IsExpired || token.WillExpireIn(tokenMins))
{
AADJWTToken newToken = DirectoryDataServiceAuthorizationHelper.GetAuthorizationToken(tenantName, clientId, password);
token = newToken;
graphService = new DirectoryDataService(tenantName, token);
}
// get tenant information
//
var tenant = graphService.tenantDetails;
QueryOperationResponse<TenantDetail> responseTenantQuery;
responseTenantQuery = tenant.Execute() as QueryOperationResponse<TenantDetail>;
List<TenantDetail> tenantInfo = responseTenantQuery.ToList();
ViewBag.OtherMessage = "User List from tenant: " + tenantInfo[0].displayName;
return View(userList);
}
}
Note: It is recommended that the JWT token is cached by the application for subsequent calls – in this block, the JWT token expiration is checked before making a second Graph API call. If the token is expired, then a new token is acquired. If a call to the Graph API is made with an expired token, the following error response will be returned, and the client should request a new token.
- Now you will add a new view to display the list of users retrieved from the Active Directory tenant. To do this, expand the Views folder of the ExpenseReport project, right-click the Home folder and select Add | View. In the Add View dialog, set the view name to Users and click Add.
Adding Users View
- Replace the code of the Users view with the following block.
(Code Snippet - Introduction to Windows Azure AD - Ex2 Users View)
CSHTML
@model IEnumerable<Microsoft.WindowsAzure.ActiveDirectory.User>
@{
ViewBag.Title = "Users";
}
<h1>@ViewBag.Message</h1>
<h2>@ViewBag.OtherMessage</h2>
<table>
<tr>
<th>
DisplayName
</th>
<th>
UPN
</th>
<th></th>
</tr>
@if (User.Identity.IsAuthenticated)
{
foreach (var user in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => user.displayName)
</td>
<td>
@Html.DisplayFor(modelItem => user.userPrincipalName)
</td>
</tr>
}
}
</table>
- In the Solution Explorer, expand the Views/Shared folder and open _Layout.cshtml. Find the <nav> element inside the <header> section and add the following highlighted action link to the Users action method of the HomeController.
CSHTML
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
<li>@Html.ActionLink("Users", "Users", "Home")</li>
</ul>
</nav>
Verification
Press F5 to run the application. The single sign-on experience is the same as you saw in the previous exercise, requiring authentication using your Windows Azure AD credentials.
Once you have successfully authenticated using your credentials, select the Users tab from the top right menu.
Users Action Link
- You should see the Users view displaying the list of users from the Active Directory tenant.
Displaying Users From AD Tenant
Download the ExpenseReport project here:
Concepts in the Code
Anti-Forgery Protection
Specifying that the name identifier is the claim type identifier
Anti-Forgery
Extracting the full name from the claims principal
We can extract attributes, such as the full name, from our our claims principal. This information can then be displayed to the user with a a webpage.
Getting the last name out of the ClaimsPrincipal
Navigating the graph API
From the user interface you can request a list of users. This opens the door for you to create your own self service or management portal.
Getting a list of users
Using the directory data service
This is a detailed code snippet showing how to get a list of users using the identity code/libraries built into Visual Studio.
How to get a token and extract the users
Validating the user list with the portal
You can see that the list of users we got from the code is the exact same list of users at the Windows Azure portal.
Using the portal or code to get the list of users
Summary
By completing this hands-on lab you have learned how to:
- Create a new Windows Azure Active Directory tenant.
- Provision an MVC application in the AD tenant.
- Configure application's sign-on and sign-out settings.
- Query Active Directory data using Graph AD API.
.
Comments
Anonymous
May 21, 2014
Very Nice blog..... really helps me .Anonymous
June 04, 2014
For visual studio 2013 no need to download identity access extension. Just take update2 for visual studio 2013 and while creating new project change authentication with federation url and relaim url.Anonymous
June 04, 2014
For visual studio 2013 no need to download identity access extension. Just take update2 for visual studio 2013 and while creating new project change authentication with federation url and relaim url.Anonymous
September 22, 2014
I don't quite understand the logic of checking to see if a token expired or not, and, if yes, getting a new token. We just got the token a few lines above. Why calling the same API with the exact same parameters again will get us a different, valid token?