This document will show you how to configure a .NET application to perform web single sign-on against your Windows Azure AD enterprise directory.
Overview
This walkthrough will show you how to use Windows Azure AD 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.
A web single sign-on solution typically entails configuring a web application to outsource its authentication functions to one external entity, commonly referred to as Identity Provider (IdP). 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.
The authority (or IdP) handles the authentication experience, and it usually requires the web application to be already known via some provisioning process. Upon successful authentication, the browser gets redirected back to the web app along with a security token carrying information about the incoming user; the application validates the token, typically via some identity-aware middleware, and if the check succeeds the user is considered authenticated and is signed in.
That high-level description applies to Windows Azure AD as well. This document will show you how to use Visual Studio 2012 and the Windows Identity Foundation (WIF) classes in the .NET Framework 4.5 to configure an MVC 4 application to use a web sign-on protocol. It 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.
The goal of this walkthrough is to help you understand how Windows Azure AD operates: that requires going beyond the direction for putting together the simplified solution here described. Besides providing you with the concrete instructions to build a working sample, the document will also introduce artifacts and concepts that will be useful for you to get to know Windows Azure AD and understand how to take advantage of its features beyond the specific scenario discussed here. Those extra sections, formatted as box notes, aren’t strictly necessary for executing the walkthrough; however, if you are interested in using Windows Azure AD in your own solutions, it is recommended that you read those parts as well.
Outline of Sections
This tutorial portion of this document is organized in the following sections:
- Prerequisites: This section lists all the requirements that must be met for you to complete the walkthrough.
- Solution Architecture: This section provides a high level introduction of how a Web SSO solution for LoB (Line of Business) applications look like. We’ll examine the functional components that make SSO happen, setting up the wireframe that you’ll later flesh out by following the document’s instructions.
- Working with Your Windows Azure AD Directory Tenant: This section introduces Windows Azure AD tenants and the features that will come into play in the scenario. It will also briefly describe the main elements of the Active Directory section of the Windows Azure Management Portal.
- Connecting the Application to Windows Azure AD: This section shows you how to use the Identity and Access Tools for Visual Studio 2012 for enabling web single sign-on in the MVC application, and tie the authentication settings to the specific Windows Azure AD tenant of choice.
- Advanced Topics: This section goes beyond the basics, digging deeper in some key topics and covering some of the other tasks you might need to perform to move your application to the next level.
Prerequisites
This following prerequisites are required to complete this tutorial:
- An Internet connection
- An active Windows Azure subscription: You can get a 90 day free trial here: Windows Azure Free Trial
- Visual Studio 2012 Professional or Visual Studio 2012 Ultimate: You can download a free trial here: Visual Studio Free Trial
- Identity and Access Tools for Visual Studio 2012
Solution Architecture
This walkthrough focuses on the following scenario: a developer has a web application that he plans to deploy in the cloud, and he only wants users from a Windows Azure Active Directory tenant to be allowed access. To accomplish this, he will need to:
- Register the web app in your Windows Azure AD tenant. Once the app is known, Windows Azure AD will accept users’ requests to authenticate against it.
- Add something in front of your app, so that:
- Unauthenticated requests can be blocked and redirected toward the correct Windows Azure AD tenant for user authentication
- Users who authenticated with Windows Azure AD can be recognized and granted access
- Unauthenticated requests can be blocked and redirected toward the correct Windows Azure AD tenant for user authentication
We will implement the first step by working with the Windows Azure Management Portal. 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.
Step #2 can be implemented using a variety of high level protocols meant to allow authentication operations across organizational boundaries, or even the Internet.
In the .NET platform, the second step boils down to configuring the classes that .NET offers out of the box for working with claims-based identity and federated authentication. Those classes are collectively known as Windows Identity Foundation (WIF), and they include HTTP modules and config settings which can be used to add the interception layer performing the redirection and authentication tasks introduced in #2. Visual Studio 2012 offers tools to help you to automatically configure web apps to use WIF to outsource authentication to external authorities which support specific web SSO protocols such as WS-Federation; this walkthrough will show you how to use such tools with Windows Azure AD.
Working with Your Windows Azure AD Directory Tenant
The first thing we need to do in our walkthrough is ensuring that you have a Windows Azure AD tenant to work with in the Windows Azure Management Portal.
Windows Azure Active Directory is the service that provides the identity backbone of Microsoft offerings such as Office 365 and Intune. If you subscribe to any of those services, you already have a Windows Azure AD tenant that your users use to sign in. If you want to reuse that tenant, as of today you can do by creating a new Windows Azure subscription and using ad administrator user from that tenant at sign up time. This walkthrough will not provide detailed guidance on how to perform that process.
In this walkthrough we will focus on the case in which you do not have an existing Windows Azure AD tenant. The first thing we need to do is to ensure that you have a Windows Azure AD tenant to work with in the Windows Azure Management Portal. The Windows Azure Management Portal provides a mechanism for you to create a new tenant directly from the Management Portal’s pages.
Create a New Directory Tenant and Add a User
- Navigate to http://manage.windowsazure.com and sign in with the Microsoft Account associated to your Windows Azure subscription. When you have signed in, look through the list of tabs on the left hand side of the screen and locate the Active Directory tab; click on it.
The screen you see here is Active Directory’s home page in the Windows Azure Management Portal. The top area offers two different headers. The Access Control Namespaces header refers to the namespaces created via the ACS2.0 service; this walkthrough will not focus on that part. The Directory header leads to the area of the Management Portal featuring operations on directory tenants; that’s where most of our activities will take place. - As shown in the screenshot above, the Windows Azure Management Portal detects that your user does not have any directory tenant associated to it and offers you the chance of creating one. Click Create Your Directory.
You are presented with a dialog which will gather the essential information needed to create a directory tenant for you. Let’s go through the various fields, bottom to top:
- 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<tenantname>.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.
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. - 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.
- 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.
That Microsoft Account is listed here to signal that it has Global Administrator privileges for the tenant, however that holds only for operations performed through the Windows Azure Management Portal UI. That Microsoft Account cannot actually authenticate against the directory tenant for flows such as web SSO, hence it cannot be used as a test user for our web SSO walkthrough.
Let’s add a new user to the directory, so that we will be able to exercise the web SSO scenario later in the document. - Click on the Add User command in the bar at the bottom of the screen. You’ll be presented with the dialog depicted below.
The Add User dialog begins by asking you if you want to create a directory user or if you want to add an existing Microsoft Account (which will have the same limitations as the Microsoft Account currently in use for administering the subscription). We need a directory user for our workflow, hence let’s go ahead and pick the New user in your organizationentry. - Choose a username, then click the arrow on the bottom-right corner.
In the next screen you can choose some basic user attributes. The role you assign to the user will determine what the user can do when accessing the directory. - Once you filled the values in, click the arrow on the bottom right corner to move to the next screen.
In the last step, 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. Please save the temporary password somewhere, as we’ll need it once we’ll have all the components in place to test the scenario.
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.
Create an ASP.NET MVC App
- Let’s begin our work on the application bits. Open Visual Studio, click New Project and pickASP.NET MVC 4 Web Application. In the New ASP.NET MVC 4 Project window, selectIntranet Application, make sure the view engine is set to Razor, then click OK. In this walkthrough we’ll use ExpenseReport as the project name.
Note This walkthrough assumes that your Visual Studio installation is configured with its default settings. If you changed some of the basic configurations (such as where web applications are hosted at development time) you’ll have to adjust the instructions accordingly.
You can apply the instructions in this walkthrough to any existing VS 2012 web application, MVC or Web Forms, provided that you don’t have any logic which significantly alters the ASP.NET request processing pipeline. For simplicity, however, here we are building a new project from scratch.
Note This walkthrough provides detailed instructions on how to set up a .NET solution, however the same results can be achieved when targeting other platforms and programming stacks. Windows Azure AD uses open protocols in its web sign-on features, and every major platform features libraries and tools supporting such protocols. The detailed steps will have to be adjusted to accommodate the syntax and practices of every stack, however the high level task subdivision will apply across the board. - IIS Express makes it very easy to enable HTTPS directly from Visual Studio. Select your project in the Solution Explorer, then in the Properties pane, switch SSL Enabled toTrue.
You will see that the SSL URL, previously empty, will be populated with a new address. Select it and copy it on the clipboard. - Now we need to let Visual Studio know that we always want to use the HTTPS endpoint during debug. Go back to the Solution Explorer, right-click on the project and chooseProperties. Choose the Web tab on the left, scroll down to the Use Local IIS Web serveroption and paste the HTTPS URL in the Project Url field. Save settings (CTRL+S) and close the property tab.
At this point we have an application that is suitable to be configured to leverage Windows Azure AD for sign-on. The next step will be to let your Windows Azure AD tenant know about this specific app.
Register a New Application
- Minimize Visual Studio and go back to the Active Directory tab in the Windows Azure Management Portal. Earlier in the walkthrough we worked in the Users area; we’ll now work in the Integrated Apps area. Click the corresponding header in the top area of the screen.
This area is dedicated to listing all the applications that are registered in your directory tenant. We say that an application is “registered” in a tenant when:
- The application has an entry in the directory, which describes its main coordinates: name, associated endpoints, and so on. More details later.
- The application itself has been granted permission to perform some operation on the current directory tenant: the operations range from requesting a sign-on token to the ability to query the directory. Once again, more details later.
Important No application can take advantage of Windows Azure AD without having been registered: this is both for security reasons (only apps that the administrator approves of should be allowed) and practical considerations (interaction with Windows Azure AD entails use of specific open protocols, which in turn require the knowledge of key parameters describing the app). - The application has an entry in the directory, which describes its main coordinates: name, associated endpoints, and so on. More details later.
- Given that we just created this directory tenant from scratch, the list of registered applications is still empty. In fact, the first entry is going to be for the application we just created in Visual Studio: this section will be entirely about registering it as an app.
Given that this is the very first app, start the process by clicking the Add button on the Windows Azure Management Portal command bar at the bottom of the screen. Then you will be prompted with the screen below:
The process of registering one app through the Windows Azure Management Portal is structured as a classic wizard, in which subsequent screens break down the gathering of the required information according to your choices.
The figure above shows the first of such screens. The options offered are straightforward:
- Display name: the text entered here is used as human-readable moniker to refer to the app whenever a user -- be it an administrator managing the registered apps list or a customer deciding to grant directory access to the app – needs to do something about it. There is more info about this in the Developing Multi-Tenant Web Applications with Windows Azure AD paper.
- Access type: this set of radio buttons allows you to specify what operations the app should be allowed to perform against the directory tenant. For the purposes of this tutorial, in which our goal is to simply configure web sign-on with our app, the proper choice is Single sign-on.
Note Other papers will delve deeper in the topic of application permissions; however here we’ll briefly touch on the principles behind it in case you want to know what happens behind the scenes.
- Display name: the text entered here is used as human-readable moniker to refer to the app whenever a user -- be it an administrator managing the registered apps list or a customer deciding to grant directory access to the app – needs to do something about it. There is more info about this in the Developing Multi-Tenant Web Applications with Windows Azure AD paper.
- Once entered the application’s name and chosen the Single sign-on access type, click on the arrow on the lower right corner to move to the next screen.
In this screen the Windows Azure Management Portal gathers important coordinates which the service needs to drive the sign-in protocol flow. Here there’s what you need to enter:
- APP URL: this parameter represents the address of your web application. In this example, this corresponds to https://localhost:44341/, the address assigned by IIS Express to your application. If you followed the instructions exactly until now you should still have it in the clipboard, ready to be pasted. The value you entered will work for the duration of the development phase: once you’ll deploy your application to its target staging or production environment, you'll have to come back to the Management Portal and modify the address to match the new application’s location. Later in the walkthrough we’ll discuss how to do that.
Warning 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.
Note 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. One possible strategy is to append something to the APP URI value as a differentiator. - APP URL: this parameter represents the address of your web application. In this example, this corresponds to https://localhost:44341/, the address assigned by IIS Express to your application. If you followed the instructions exactly until now you should still have it in the clipboard, ready to be pasted. The value you entered will work for the duration of the development phase: once you’ll deploy your application to its target staging or production environment, you'll have to come back to the Management Portal and modify the address to match the new application’s location. Later in the walkthrough we’ll discuss how to do that.
- Once you entered APP URL and APP ID URI you can click on the checkbox button on the lower right corner.
That concludes the registration process, your app has now its own entry in the directory tenant and Windows Azure AD is ready to handle web authentication on its behalf.
The screen informing you of the successful registration provides you with the information you need to configure your web application to use Windows Azure AD for sign-on. Namely: the Enable single sign-on with Windows Azure AD section contains a couple of settings that you’ll need to paste back in Visual Studio.
Keep your browser open on this page and switch back to Visual Studio for the next task of the walkthrough.
Connecting the Application to Windows Azure AD
Now that Windows Azure AD is ready to issue authentication tokens for your application, the last step to enable web sign-on is to configure the application itself to handle requests with the right authentication protocol. The protocol enforcement is what allows the application to invoke Windows Azure AD - and specifically your directory tenant - to take care of user authentication at the beginning of a user’s work session with the app.
It’s important to understand some of the background information on authentication mechanics when using web sign-on protocols. You will find more details in the advanced section.
The project template we have chosen is the MVC 4 Intranet application. That template normally relies on Windows integrated authentication to ensure that the app’s user is authenticated. That mechanism operates at the network level: it is applied to any services published on the intranet, without the need of adding any authentication logic to the application itself.
When you deploy an application outside of your intranet, as it is the case for cloud apps, you can no longer rely on network-level authentication. The most common strategy for dealing with authentication in those cases includes adding some kind of middleware in front of your application, which re-creates at higher level the necessary authentication check. The extra layer can take care of intercepting unauthenticated requests, enforcing authentication protocols, redirecting users to authenticate off-application, returning to the app info about the authenticated user, managing sessions and in general all the tasks that are necessary for access control.
This strategy is consistently applied in the industry across all the choices of platforms, development stacks and sign-on protocols; what goes on the wire and the programming model will vary, but the general pattern remains largely the same.
In this walkthrough we are going to connect the application to Windows Azure AD via the WS-Federation protocol: this is only one of the possible choices for implementing Web SSO, SAML-P being the other most common choice.
The .NET Framework 4.5 supports WS-Federation natively: all the classes needed for enforcing the protocol flow, processing authentication and handling sessions in the context of ASP.NET applications are present in the box.
In a nutshell: .NET 4.5 offers a set of HttpModules which are meant to be instantiated in the application’s HTTP pipeline. Those modules are designed to refer to well-known configuration sections, which contain the protocol coordinates of both the application and the authenticating authority (in this case, your Windows Azure AD tenant). As requests flow in, the modules examine them and enforce the authentication protocol as appropriate: for example, upon receiving an unauthenticated request the modules will read the Windows Azure AD tenant’s coordinates from config, use them to compose a WS-Federation sign-in message and use it to automatically redirect the user to authenticate with Windows Azure AD.
Note |
---|
The subset of classes in the .NET Framework 4.5 dedicated to claims based identity related tasks is known as Windows Identity Foundation (WIF). Applications targeting earlier versions of the framework (3.5 and 4.0) can also implement the steps described in this walkthrough, by taking advantage of an earlier version of WIF which was released out of band as a standalone library (download here). However note that the step by step instructions would differ, given that the two versions are not fully compatible (the classes live in different namespaces) and that you’d have to use tooling for different Visual Studio versions (2008 and 2010, download here).
|
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. In this walkthrough you will have to write very little code, thanks to the fact that the tooling will auto-generate most of it for you.
- Now that you know how we are going to implement web sign-on, let’s use the Identity and Access Tool to configure your application. In Solution Explorer, right-click on your applications’ project, then click Identity and Access… from the context menu.
Visual Studio will show the dialog depicted below.
You will do all your work in the Providers tab, the one currently shown. For the purpose of this walkthrough, we will ignore all the options we don’t need for the task at hand. - The tool lists various authority types you can use to outsource authentication. In our specific case, we are interested in using a Business Identity Provider: click on the corresponding entry, second option from the top.
As you select the option, the corresponding UI elements are displayed in the panel below. The information requested by those control matches exactly with the entries displayed at the end of the application registration process described in the earlier section. Here there’s what you have to enter, from the bottom to the top:
- Enter the APP ID URI (realm) of your application: This is the identifier of your application, as you defined it during the registration. Switch back to the browser window showing the Management Portal, copy the corresponding value from theUpdate your code with your App ID URI field and paste it here.
- Enter the path to the STS metadata document : The “STS metadata document” is a file containing a machine-readable description of the authority you want to connect to: the tool will consume it to determine the value of parameters that are essential to the sign-on flow (more details below). Every Windows Azure AD tenant exposes one such document; its location is provided at the end of the registration process. Switch to the Management Portal, copy the corresponding value from the app registration page, switch back to the tool and paste the path in this field.
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.
- Enter the APP ID URI (realm) of your application: This is the identifier of your application, as you defined it during the registration. Switch back to the browser window showing the Management Portal, copy the corresponding value from theUpdate your code with your App ID URI field and paste it here.
The following list describes the main entries added to the web.config by the tool. For a more detailed description, please refer to the advanced section of the document.
- <section> entries for system.identityModel and system.identityModel.services: These are necessary for the config to understand the identity-specific config settings.
- <authorization> settings in <system.web>: The tool automatically change the existing ASP.NET authentication settings to require that every request to the app must be authenticated. This enforces the so called “blanket redirect” behavior, in which every unauthenticated request gets redirected to the authentication authority (as opposed to having parts of the app available to unauthenticated users). Such behavior is the default in LoB applications, where authentication is often silent given that the user is already signed in with the authority. If the developer wants to change this behavior to provide authentication requirements on a case by case basis, they can simply change <authorization> settings accordingly.
- WSFederationAuthenticationModule (FAM) and SessionAuthenticationModule (SAM) in <system.webServer/modules>: Those entries add in the application’s HTTP pipeline the HttpModules which take care of enforcing the use of WS-Federation for authentication. The FAM is the module responsible for protocol enforcement: sign-on requests, token validation sign out management are the main flows it is responsible for. The SAM handles sessions: specifically, it generates session cookies, validates them and enforce their presence at every request, handles session’s length, and so on. Their behavior is driven by the config element described below.
- The <system.identitymodel/identityConfiguration> section: This element determines the behavior of the app during the authentication phase. For example: in the sub-element ValidatingIssuerNameRegistry it stores the list of authorities that are trusted for providing authentication services, by recording their names and the certificates they use for signing.
- The <system.identitymodel.services/federationConfiguration> section: This section provides the coordinates that are necessary for driving WS-Federation flows: the address of the authority to be used for sign-on requests, the identifier of the app itself to be included in requests, and so on.
The auto-generated config is all you need for taking advantage of Windows Azure AD for web sign-on: you don’t need to write any authentication-specific code in the application itself. If you want to access user identity’s information you can easily do so by querying the claims in the current principal. For example, say that you’d like to access the first and last names of your current user. You will be able to do so using the following code, without the need of knowing anything about how authentication took place:
//... using System.Security.Claims; namespace ExpenseReport.Controllers { public class HomeController : Controller { 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(); } //...
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.
Every ClaimsPrincipal contains a collection of claims, attributes describing the current user as asserted by the authority that authenticated him/her. In our walkthrough, the claims in the principal are the ones issued in the token by Windows Azure Active Directory: for a complete list of the available claims please refer to the online documentation.
Windows Azure AD issues a fixed set of claims for the authenticated users. Below there’s a quick reference of all the claims you can expect from Windows Azure AD; you can find a complete description in the documentation.
Type | Value in Sample | Description |
---|---|---|
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier |
S40rgb3XjhFTv6EQTETkEzcgVmToHKRkZUIsJlmLdVc |
Unique, immutable, non-reusable, directed identifier of the authenticated user for the current application |
http://schemas.microsoft.com/identity/claims/objectidentifier |
528b2ac2-aa9c-45e1-88d4-959b53bc7dd0 |
Identifier for the user in the directory. Useful for directory queries about the user. |
http://schemas.microsoft.com/identity/claims/tenantid |
cab1a5ac-f33b-45fa-9bf5-f37db0fed422 |
Identifier of the directory tenant |
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname |
John |
Given name of the user |
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name |
user@test04-realm2 |
UPN of the user |
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname |
Doe |
Last name of the user |
http://schemas.microsoft.org/identity/claims/identityprovider |
https://sts.windows.net/cab1a5ac-f33b-45fa-9bf5-f37db0fed422/ |
Identifier of the authority that authenticated the user, as expressed in the web sign-on protocol (in this case, WS_Federation) |
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’ll want to add: support for sign out and automatic refresh of the authority’s protocol coordinates.
The next two sections will detail how to add those two features: it is recommended that you go through those as well before moving to the “Running your App” section.
Configuring Sign Out
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. WS-Federation is no exception, and offers a complete sign out flow that is fully implemented in WIF's object model. In this subsection we will discuss how to add distributed sign out capabilities to the sample application: that boils down to providing the right hookups in the user experience to trigger the signout flow, and to generate the appropriate signout message to be set to your Windows Azure AD tenant.
Add a Sign Out Controller
- Begin by adding a SignOut controller to the application. You can easily do so by locating the Controllers folder under the project in Solution Explorer, right-click on it and chooseAdd, then click Controller. Name it SignOutController, choose Empty MVC Controller(it is usually the default setting), and then click Add.
- We’ll need to use classes from some new assemblies, hence we’ll have to add references to those. Again in Solution Explorer, right-click on the References node, choose Add Reference…, type system.identitymodel.services in the Search Assemblies field, and select the corresponding assembly from the main list. Press OK.
- Go back to the newly created SignOutController.cs file. Add to the using directives the following entries:
using System.IdentityModel.Services; using System.IdentityModel.Services.Configuration;
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()); }
- The first method, Index(), serves request of the formhttps://localhost:44341/SignOut. That is the address of a view you will add in few steps later in the walkthrough. Its purpose it to signal a successful sign-out, and we will use it as such in the next method.
- The SignOut() method serves request of the formhttps://localhost:44341/SignOut/SignOut, and contains the main sign out logic.
- The first line retrieves the object that WIF uses for keeping track of the WS-Federation settings in the web.config: we will need it to craft a sign out message tailored to the current application.
Note Referring to the config values, as opposed to hardcode values or sourcing them from custom repositories, is usually good practice given that it makes your code adaptive and aligned with the rest of the protocol settings: the logic will keep working no matter how many times settings are changed in the config file, before and after deployment. - The second and third lines create the return address we want the authority to use at the end of the sign out flow. We want that address to point to the View discussed earlier: hence, the code obtains the URL of the current request and eliminates the trailing ‘SignOut’. Deriving the address from the request guarantees that it correctly resolves for the client, whereas obtaining the address from the hosting layer might result in internal ports issues when using a load balancer.
- The fourth line uses WIF to craft a WS-Federation sign-out message, passing in the authority’s URL and the return address defined one line before. You could easily create the message directly in its wire form, however using the WIF object model will help you to write more concise code and ignore most of the syntax details. If you are interested in seeing how a sign out message looks like, make sure to capture an HTTP trace when you’ll run the app in a later section or consult the specification here.
- The fourth line adds to the message the identifier of the current app, as recorded in the realm attribute of the <wsFederation> configuration element.
- The fifth line uses the SAM (described earlier in the autogenerated config description) to clean up the local session: that includes deleting the session cookie generated at sign-on time, and any local resource cleanup that might be necessary.
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.
- The first method, Index(), serves request of the formhttps://localhost:44341/SignOut. That is the address of a view you will add in few steps later in the walkthrough. Its purpose it to signal a successful sign-out, and we will use it as such in the next method.
Add a Sign Out View
The view used here is going to be very simple: as mentioned, its purpose is just to create a meaningful return point for the sign out flow.
- In the Solution Explorer, right-click on the Views node and add a SignOut folder.
- In that folder, add a view by right-clicking the folder and clicking Add, then click View. Call the new view SignOut as well. Put some placeholder presentation code in the View file (SignOut.cshtml) to signal that signout took place. For example:
@{ ViewBag.Title = "SignOut"; } <h2>You have successfully signed out</h2>
- As you might you might recall from the former section, we configured the application to handle authentication via blanket redirects. That means that, if we try to access this View after a successful sign out (as we are meant to) we 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.
Locate the first occurrence of the <system.web> element, and just above it paste the following snippet:
<location path="SignOut"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location>
Add a UI for Triggering Sign Out
- Now that the app has the capability of signing out, all that’s left is surfacing the feature to the user experience. Here there’s a very simple way of doing so: open _layout.cshtml from the Views\Shared path in the solution explorer. Search for the string “Hello,” to locate the code which takes care of rendering the login info at the top of the typical MVC 4 layout, then modify the login section as follows:
<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>
That will add a sign out command on the right of the logged user’s greeting, so that a sign out action can be triggered from any view.
Add 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. Moreover, it saved key information used at authentication time to validate that the incoming token actually originated from your Windows Azure AD tenant: those are the issuer name representing your tenant and the public key (in form of X.509 certificate) that should be used to verify the token’s signature.
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. In case of emergency keys might be renewed off-cycle, with little or no warning.
Every time the signing key is rolled, your application settings must be changed accordingly: following the approach shown in the walkthrough until now, that would mean re-running the tool to read the new metadata document and refresh the web.config entries.
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. Below there’s an example of how to implement such feature.
- Use Solution Explorer, as described earlier in the document, to add a reference to the assembly System.IdentityModel.
- Add the following using directives to the Global.asax file:
using System.Configuration; using System.IdentityModel.Tokens;
- Then add the following method to the Global.asax file:
//... protected void RefreshValidationSettings() { string configPath = AppDomain.CurrentDomain.BaseDirectory + "\\" + "Web.config"; string metadataAddress = ConfigurationManager.AppSettings["ida:FederationMetadataLocation"]; ValidatingIssuerNameRegistry.WriteToConfig(metadataAddress, configPath); }
- To insert RefreshValidationSettings() in the application’s lifecycle, invoke it fromApplication_Start() as shown below.
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); RefreshValidationSettings(); }
Important |
---|
There are some extra precautions you need to apply when auto-refreshing the validation keys from the application. The main threat you need to mitigate is DNS hijacking, where an attacker uses malware to point you to a malicious metadata document and induce your app to trust the wrong keys. If you don’t override the .NET defaults for handling HTTP requests, the above scenario is already mitigated thanks to the fact that metadata documents are hosted on HTTPS endpoints. A DNS hijacking can redirect requests to a malicious endpoint, but such endpoint cannot pass the HTTPS server validation: not actually owning the domain on which metadata docs are hosted, the attacker cannot obtain an issued certificate for it, hence the client will be able to detect an issue with the server and avoid being misdirected. Occasionally some development scenarios will require you to turn off HTTPS validation (typically via the ServicePoint class). If you use the automatic metadata refresh logic shown in this section, it is critical that you restore the HTTPS validation settings before deploying your application in production.
|
Run the Application
- We are now finally able to observe the application in action. Press F5: a browser window will open, attempting to access the URL specified in the project settings in the "Create an MVC App” section.
First, you will get a certificate error. This is expected behavior, click Continue to this website (not recommended). Do not ignore this error in a production application, but it’s acceptable for the purposes of this walkthrough.
If you keep an eye on the address bar, you might observe for a brief moment the app’s URL; however the FAM module in front of the app immediately recognizes the call as unauthenticated, reads what to do from the config and triggers the sign-in redirect to Windows Azure AD. 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.
Note The new user account you created earlier cannot be used to manage your Windows Azure subscription if you initially signed in to the Management Portal using a Microsoft Account. If you attempt to navigate back to the Management Portal after you have signed in to the application as the new user, you will get an error message. Instead, you must sign in to the Management Portal using the account you used to create your directory tenant. If you initially signed in to the Management Portal using an Windows Azure AD account and if the new user you created earlier was given the Global Administrator role, this new user can manage your Windows Azure subscription. - Enter the credentials of the user you created in your Windows Azure tenant in the first section of the walkthrough. Press the Sign in button.
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.
As the authentication successfully takes place, WIF processes the claims from the incoming authentication token, which in turn are used by the simple display code we added in the home controller. From now on you can navigate through the site without the need of authenticating again: every postback will carry the session cookie handled by the SAM module. - To observe what happens when you terminate the session, click on the Signout link on the top right corner. You’ll observe the redirects we coded earlier, which will eventually land on the view below.
To verify that you are actually signed out, click on any other UI element: the authentication cycle will start over.
Advanced Topics
The walkthrough portion of the document showed you the essential steps you need to perform to add web sign-on to your web application. The rest of the document will go beyond the basics, digging deeper in some key topics and covering some of the other tasks you might need to perform to move your application to the next level.
Deploying the App in Windows Azure Web Sites
In this section you will learn how to modify your application’s settings to deploy and run it in Windows Azure Web Sites. The application remains largely unchanged: the only things requiring attention are accommodating for your app’s new address and session management.
Create a New Windows Azure Website
This part of the document requires you to have a Windows Azure Web Site to target for your application’s deployment. If you already have one web site available, you can use it; if you don’t, please refer to this document for learning how to create and publish a Windows Azure Web site. If you follow the tutorial in that document, please stop right after having downloaded the publishing profile: there are a couple of things we need to adjust before deploying the application.
Adjust the application’s settings in the Windows Azure Management Portal
If you recall the section about application registration, you’ll remember that one key parameter defining your application in the Windows Azure AD UI is the URL of the application itself. The walkthrough steps until now assumed the local IIS express as the app’s location, however a deploy to Windows Azure Web Sites means that the application’s URL will change and that the settings in Windows Azure AD will have to reflect that.
- Navigate back to the Management Portal; select the Active Directory tab on the left; click on your directory tenant; choose the Integrated Apps header; click on the entry corresponding to the application you’ve been working with. Click on the Configure header; you’ll navigate to a screen that will allow you to modify the application’s settings you entered at creation time. For the sake of this tutorial, ignore the top areas of the screen and scroll down to the single sign-on section.
- Locate the REPLY URL text box, and enter there the address of your target Windows Azure Web Site (for example, https://aadga.windowsazure.net/). That will let Windows Azure AD to return tokens to your Windows Azure Web Site location upon successful authentication (as opposed to the development time location you used earlier in the thread). Once you updated the value, hit SAVE in the command bar at the bottom of the screen.
Note |
---|
You might have noticed that the APP ID URI is still using the localhost-based value you created earlier in the document. Technically, as long as the identifier is in URI form and unique across all the apps in the current directory tenant, for the kind of apps discussed here any value will work; which is why the main instructions do not include updating that value. However for manageability purposes you might want to modify the APP ID URI to carry a value that is more representative of your application. A typical example would be some derivative of the reply URL value. Note that, if you change the APP ID URI value, you’ll need to apply more extensive changes to the app before deploying. More details later.
|
Prepare the Application to Run in Windows Azure Web Sites
The web sign-on configuration is for the most part cloud-ready: there is only one change you need to apply, largely due to Windows Azure Web Sites’ features.
The web sign-on process results in the creation of a session cookie, which gets sent at every request from the authentication instant on. The session cookie is created by the WIF middleware, and by default it is signed and encrypted via DPAPI (see this document for background information) in order to avoid abuses from the client (such as changing the list of claims to elevate privileges). However IIS settings in the Windows Azure Web Sites prevent the use of DPAPI for protecting sessions, hence you need to change the way in which WIF secures the associated cookie. The .NET Framework 4.5 offers an alternative out of the box, which leverages the MachineKey (see documentation here) and works without issues in Windows Azure Web Sites.
The Identity and Access Tool makes this change a very simple one.
- Right-click on the project in Solution Explorer, choose Identity and Access… and select the Configuration tab. You’ll see something to the effect of the following screenshot:
- Simply check the Enable web farm ready cookies flag and press OK. The tool will take care of adding the necessary elements in web.config (in practice, substitute the default class SessionSecurityTokenHandler with MachineKeySessionSecurityTokenHandler) to switch to MachineKey as cookie protection method.
Note If in the former step you did change the APP ID URI in the Windows Azure Management Portal, you can use this UI to easily apply those changes to your project: just paste theAPP ID URI value in the top two text fields and hit OK. The tool will apply those changes in the right places in the config file. <customErrors mode="Off" />
in the <system.web>section of the web.config file. That will help you to troubleshoot should you stumble in issues at deployment time, however please make sure to turn those back on before moving to production: attackers might use the detailed error messages to probe your app for openings, andcustomError
will prevent that from happening.
Publish and Test the Windows Azure AD feature in Your Windows Azure Web Site
That’s all you need to do for preparing your application to run as Windows Azure Web Site. Use your publish settings to deploy the application, then open a browser, navigate to the azurewebsite.net address of your app and follow the same flow discussed in the app testing section of the walkthrough: given that we designed all custom logic to be location independent, you’ll be able to perform the same operations you experienced on premises.
Windows Identity Foundation (WIF) Settings in Detail
The Identity and Access Tool automatically generates the config settings that are necessary for your app to integrate with your Windows Azure AD tenant via WS-Federation. In the best case, you never need to actually see those settings; however there are occasions in which you want to alter the default behavior, or you need to troubleshoot a problem. In those cases, finding your way through the WIF config settings can help.
The WIF classes and method used in the web sign-in flow are fully documented in MSDN; here we will present an annotated version of the web.config after the Identity and Access Tool modified it. For your convenience, we also included the changes derived from the section on publishing to Windows Azure Web Sites.
Note |
---|
For the sake of clarity, the document includes the full Web.config source; however, only the sections relevant to WIF are annotated.
|
<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
No comments for the above config.
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
In the above config, this area loads the classes that ASP.NET needs in order to read and interpret the config sections used by WIF to model the WS-Federation flow and authentication settings.
</configSections> <appSettings> <add key="webpages:Version" value="2.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="PreserveLoginUrl" value="true" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" />
No comments for the above config.
<add key="ida:FederationMetadataLocation" value="https://login.windows.net/ec4187af-07da-4f01-b18f-64c2f5abecea/federationmetadata/2007-06/federationmetadata.xml" /> <add key="ida:Issuer" value="https://login.windows.net/ec4187af-07da-4f01-b18f-64c2f5abecea/wsfed" /> <add key="ida:ProviderSelection" value="productionSTS" /> </appSettings>
For the above config, those appSettings entries are captured by the Identity and Access Tool, to keep track of important settings (such as the address of the metadata document, which we used in the key rollover section) that would not be saved elsewhere.
<location path="FederationMetadata"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <location path="SignOut"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location>
For the above config, those two <location> elements carve two areas in the web application that can be accessed without authentication requirements (see below). The FederationMetadata section is created by the Identity and Access Tool: the tool creates a metadata document describing the application, which can be used by authorities to provision the app. You added the SignOut section yourself as part of the instructions on how to implement web Sign out.
<system.web> <authentication mode="None" /> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" requestValidationMode="4.5" /> <!--Commented by Identity and Access VS Package--> <!--<authentication mode="Windows" />--> <authorization> <deny users="?" /> </authorization>
For the above config, by default, the Identity and Access Tool sets the ASP.NET authentication and authorization settings so that every part of the web app (apart from the exceptions above) requires users to be authenticated before serving requests. While that is usually appropriate for LoB apps, at times developers want to retain areas which can be accessed anonymously: if that is the case for you, change the settings here accordingly.
<pages> <namespaces> <add namespace="System.Web.Helpers" /> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Optimization" /> <add namespace="System.Web.Routing" /> <add namespace="System.Web.WebPages" /> </namespaces> </pages> <customErrors mode="Off" /> <machineKey decryptionKey="998D0533DD570FDCA86A945893F0B2BFC0E1F3645E148F35" validationKey="E739C2EA4B4470820308DA71D81160F22C0D9CD3C97709CB0679E55FDCC2D35B35563D56102F254FB4908644ECB53B3898948F54AAC4A5F0C44754A5A997B79A" /> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers>
No comments for the above config.
<modules> <remove name="FormsAuthentication" /> <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> </modules> </system.webServer>
For the above config, the entries in this section insert in the SP.NET pipeline the HTTPModules which implement the core protocol and session handling features.The WSFederationAuthenticationModule (FAM) enforces WS-Federation, by valudating incoming tokens and generating sign-on messages to the authority in accordance to the protocol’s specifications. The SessionAuthenticationModule (SAM) creates and validates session cookies, in concert with the FAM.
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-1.3.0.0" newVersion="1.3.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> </entityFramework>
No comments for the above config.
<system.identityModel> <identityConfiguration> <audienceUris> <add value="https://localhost:44342/ShiungZZZ" /> </audienceUris>
For the above config, <system.identityModel> wraps all the WIF classes-specific settings.Its first child element, IdentityConfiguration, provides a protocol-independent description of the application’s behavior. The AudienceUris list provides all the values that WIF will consider as acceptable scopes in incoming tokens for the current applications; typically, those correspond to the application’s realm (or APP ID URI, in Windows Azure AD parlance). An incoming token must declare that its intended recipient is one of the values listed here; if that is not the case, WIF will assume that this is a stolen token and will refuse the call.
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry"> <authority name="https://sts.windows.net/ec4187af-07da-4f01-b18f-64c2f5abecea/"> <keys> <add thumbprint="3A38FA984E8560F19AADC9F86FE9594BB6AD049B" /> </keys> <validIssuers> <add name="https://sts.windows.net/ec4187af-07da-4f01-b18f-64c2f5abecea/" /> </validIssuers> </authority> </issuerNameRegistry>
For the above config, the ValidatingIssuerNameRegistry element contains the list of the acceptable issuer name-signature check key tuples.In this walkthrough, the settings will reflect the values associated to your Windows Azure AD tenant: this element guarantees that no other issuer, including other Windows Azure AD tenants owned by other companies, can gain access to your application.
<certificateValidation certificateValidationMode="None"> </certificateValidation>
For the above config, this element turns off the certificate validation in the WIF pipeline. This measure is necessary in the Windows Azure AD case, given that a self-signed certificate is used: short of installing the certificate itself in the local certificate store, a chain or a peer validation would fail.Please note: this does not really diminish security for the Windows Azure AD authentication, given that the ValidatingIssuerNameRegistry guarantees the correct certificate will be used; however, if you are using WIF in the same app for trusting other issuers please be warned that those settigns would extend to those as well.
<securityTokenHandlers> <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </securityTokenHandlers> </identityConfiguration>
This section allows you to manipulate the collection of classes which WIF uses for processing incoming security tokens (the so called token handlers). It can be used to influence the behavior of individual handlers, or to add and remove handler types. In this case, the tool removed the default session handler (which is based on DPAPI and cannot work on Windows Azure Web Sites) and substitutes it with one that works with the MachineKey.
</system.identityModel> <system.identityModel.services> <federationConfiguration> <cookieHandler requireSsl="false" /> <wsFederation passiveRedirectEnabled="true" issuer="https://login.windows.net/ec4187af-07da-4f01-b18f-64c2f5abecea/wsfed" realm="https://localhost:44342/ExpenseReport" requireHttps="false" /> </federationConfiguration> </system.identityModel.services> </configuration>
For the above config, the <system.identityModel.services> is used to store WS-Federation-specific coordinates.
The wsFederation element, in particular, is here used to record the WS-Federation sign-on endpoint of your Windows Azure AD tenant; the realm (APP ID URI) of the app, to be sent as identifier at sign-on time; and other flags influencing WIF’s local behavior, such as if 401 errors from the app should always trigger a sign-in message to the authority (passiveRedirectEnabled) or if transactions on clear HTTP should eb allowed.
This element can be used to specify many more protocol parameters: those are just the absolute minimum for the sign-on flow to function.
More Management Portal Options
This document focuses on a fairly narrow task, connecting a.NET application to Windows Azure AD to perform web sign-on via WS-Federation. There are many more scenarios you can tackle, using a variety of different open protocols, leveraging any programming stack on any modern platform or working directly at the protocol level on the wire.
In the section about deploying the app to Windows Azure you saw that the Management Portal offers you the chance of changing many more aspects of your application’s registration settings: you will get to know most of those extra controls in the next walkthrough in the series. Here we will just briefly mention how you can obtain the information you need should you choose to interact with Windows Azure AD at the protocol level, for web sign-on or any other of the flows it supports.
- Open the Windows Azure Management Portal in a browser window, and navigate to theIntegrated Apps header in the Windows Azure AD section. You will notice that the command bar at the bottom of the screen contains one entry: View Endpoints. Click on it.
The dialog lists all of the endpoints you can use to interact with your Windows Azure AD tenant programmatically. Here there’s a brief explanation for all the entries:
- Federation Metadata Document: The location of the metadata document describing the Windows Azure AD tenant as a web sign-on authority. As you have seen in the walkthrough, in the section about automatic refresh of keys, this document contains WS-Federation metadata coordinates; it also contains the SAML protocol metadata in the same package. For more information, see Federation Metadata.
- WS-Federation Sign-On Endpoint: The entry point for all WS-Federation transactions. This is the endpoint you used in the walkthrough for both sign-on and sign out flows. For more information, see WS-Federation Endpoint URL.
- SAML-P Sign-On Endpoint: The endpoint used for implementing sign-on flows in the SAML protocol. For more information, see SAML Protocol Metadata and Endpoints.
- SAML-P Sign-Out Endpoint: The endpoint used for implementing sign out flows in the SAML protocol. For more information, see SAML Protocol Metadata and Endpoints.
- Windows Azure AD Graph Endpoint: Queries to retrieve directory info stored in the current Windows Azure AD tenant must be addressed to this endpoint, using the Graph API syntax. For more details, see Using the Graph API to Query Windows Azure AD.
- OAuth2 Token Endpoint: This endpoint is used for server to server authentication flows: for example, it can be used for obtaining access tokens for invoking the Graph endpoint. For more information, see OAuth 2.0 (Preview Version).
- Federation Metadata Document: The location of the metadata document describing the Windows Azure AD tenant as a web sign-on authority. As you have seen in the walkthrough, in the section about automatic refresh of keys, this document contains WS-Federation metadata coordinates; it also contains the SAML protocol metadata in the same package. For more information, see Federation Metadata.