This chapter walks you through an example of single sign-on (SSO) for intranet and extranet Web users who all belong to a single security realm. You'll see examples of two existing applications that become claims-aware. One of the applications uses forms authentication, and one uses Windows authentication. Once the applications use claims-based authentication, you'll see how it's possible to interact with the applications either from the company's internal network or from the public Internet.
This basic scenario doesn't show how to establish trust relationships across enterprises. (That is discussed in chapter 4, "Federated Identity for Web Applications.") It focuses on how to implement single sign-on and single sign-off within a security domain as a preparation for sharing resources with other security domains, and how to migrate applications to Microsoft® Windows® Azure. In short, this scenario contains the commonly used elements that will appear in all claims-aware applications.

The Premise

Adatum is a medium-sized company that uses Microsoft Active Directory® directory service to authenticate the employees in its corporate network. Adatum's sales force uses a-Order, Adatum’s order processing system, to enter, process, and manage customer orders. Adatum employees also use aExpense, an expense tracking and reimbursement system for business-related expenses.
Both applications are built with ASP.NET 3.5 and are deployed in Adatum's data center. Figure 1 shows a whiteboard diagram that shows the structure of a-Order and a-Expense.

Figure 1
Adatum infrastructure before claimsThe two applications handle authentication differently. The a-Order application uses Windows authentication. It recognizes the credentials used when employees logged on to the corporate network. The application doesn't need to prompt them for user names and passwords. For authorization, a-Order uses roles that are derived from groups stored in Active Directory. In this way, a-Order is integrated into the Adatum infrastructure.
The user experience for a-Expense is a bit more complicated. The a-Expense application uses its own authentication, authorization, and user profile information. This data is stored in custom tables in an application database. Users enter a user name and password in a Web form whenever they start the application. The a-Expense application's authentication approach reflects its history. The application began as a Human Resources project that was developed outside of Adatum's IT department. Over time, other departments adopted it. Now it's a part of Adatum's corporate IT solution.
The a-Expense access control rules use application-specific roles. Access control is intermixed with the application's business logic.
Some of the user profile information that a-Expense uses also exists in Active Directory, but because a-Expense isn't integrated with the corporate enterprise directory, it can't access it. For example, Active Directory contains each employee's cost center, which is also one of the pieces of information maintained in the a-Expense user profile database. Changing a user's cost center in a-Expense is messy and error prone. All employees have to manually update their profiles when their cost centers change.

Goals and Requirements

Adatum has a number of goals in moving to a claims-based identity solution. One goal is to add the single sign-on capability to its network. This allows employees to log on once and then be able to access all authorized systems, including a-Expense. With SSO, users will not have to enter a user name and password when they use a-Expense.
A second goal is to enable Adatum employees to access corporate applications from the Internet. Members of the sales force often travel to customer sites and need to be able to use a-Expense and aOrder without the overhead of establishing a virtual private network (VPN) session.
A third goal is to plan for the future. Adatum wants a flexible solution that it can adapt as the company grows and changes. Right now, a priority is to implement an architecture that allows them to host some applications in a cloud environment such as Windows Azure. Moving operations out of their data center will reduce their capital expenditures and make it simpler to manage the applications. Adatum is also considering giving their customers access to some applications, such as a-Order. Adatum knows that claims-based identity and access control are the foundations needed to enable these plans.
While meeting these goals, Adatum wants to make sure its solution reuses its existing investment in its enterprise directory. The company wants to make sure user identities remain under central administrative control and don't span multiple stores. Nonetheless, Adatum wants its business units to have the flexibility to control access to the data they manage. For example, not everyone at Adatum is authorized to use the a-Expense application. Currently, access to the program is controlled by application-specific roles stored in a departmentally administered database. Adatum's identity solution must preserve this flexibility.
Finally, Adatum also wants its identity solution to work with multiple platforms and vendors. And, like all companies, Adatum wants to ensure that any Internet access to corporate applications is secure.
With these considerations in mind, Adatum's technical staff has made the decision to modify both the aExpense and the a-Order applications to support claims-based single sign-on.

Overview of the Solution

The first step was to analyze which pieces of identity information were common throughout the company and which were specific to particular applications. The idea was to make maximum use of the existing investment in directory information. Upon review, Adatum discovered that their Active Directory store already contained the necessary information. In particular, the enterprise directory maintained user names and passwords, given names and surnames, e-mail addresses, employee cost centers, office locations, and telephone numbers.
Since this information was already in Active Directory, the claims-based identity solution would not require changing the Active Directory schema to suit any specific application.
They determined that the main change would be to introduce an issuer of claims for the organization. Adatum's applications will trust this issuer to authenticate users.
Adatum envisions that, over time, all of its applications will eventually trust the issuer. Since information about employees is a corporate asset, the eventual goal is for no application to maintain a custom employee database. Adatum recognizes that some applications have specialized user profile information that will not (and should not) be moved to the enterprise directory. Adatum wants to avoid adding application-specific attributes to its Active Directory store, and it wants to keep management as decentralized as possible.
For the initial rollout, the company decided to focus on a-Expense and a-Order. The a-Order application only needs configuration changes that allow it to use Active Directory groups and users as claims. Although there is no immediate difference in the application's structure or functionality, this change will set the stage for eventually allowing external partners to access.
The a-Expense application will continue to use its own application-specific roles database, but the rest of the user attributes will come from claims that the issuer provides. This will provide single sign-on for aExpense users, streamline the management of user identities, and allow the application to be reachable remotely from the Internet.

Note:
Note: You might ask why Adatum chose claims-based identity for a-Expense rather than Windows authentication. Like claims, Windows authentication provides SSO, and it is a simpler solution than issuing claims and configuring the application to process claims. There's no disagreement here: Windows authentication is extremely well suited for intranet SSO and should be used when that is the only requirement.Adatum's goals are broader than just SSO, however. Adatum wants its employees to have remote access to a-Expense and a-Order without requiring a VPN connection. Also, Adatum wants to move aExpense to Windows Azure and eventually allow customers to view their pending orders in the aOrder application over the Internet. The claims-based approach is best suited to these scenarios.Figure 2 shows the proposal, as it was presented on Adatum's whiteboards by the technical staff. The diagram shows how internal users will be authenticated.

Figure 2
Moving to claims-based identityThis claims-based architecture allows Adatum employees to work from home just by publishing the application and the issuer through the firewall and proxies. Figure 3 shows the way Adatum employees can use the corporate intranet from home.

Figure 3
Claims-based identity over the InternetOnce the issuer establishes the remote user's identity by prompting for a user name and password, the same claims are sent to the application, just as if the employee is inside the corporate firewall.
This solution makes Adatum's authentication strategy much more flexible. For example, Adatum could ask for additional authentication requirements when someone connects from the Internet, such as smart cards, PINs, or even biometric data. Because authentication is now the responsibility of the issuer, and the applications always receive the same set of claims, the applications don't need to be rewritten. The ability to change the way you authenticate users without having to change your applications is a real benefit of using claims.
You can also look at this proposed architecture from the point of view of the HTTP message stream. For more information, see the message sequence diagrams in chapter 2, "Claims-Based Architectures."

Inside the Implementation

Now is a good time to walk through the process of converting a-Expense into a claims-aware application in more detail. As you go through this section, you may want to download the Visual Studio® solution 1SingleSignOn from http://claimsid.codeplex.com. This solution contains implementations of a-Expense and a-Order, with and without claims. If you are not interested in the mechanics, you should skip to the next section.

a-Expense Before Claims

Before claims, the a-Expense application used forms authentication to establish user identity. It's worth taking a moment to review the process of forms authentication so that the differences with the claims-aware version are easier to see. In simple terms, forms authentication consists of a credentials database and an HTTP redirect to a logon page.
Figure 4 shows the a-Expense application with forms authentication.

Figure 4
a-Expense with forms authenticationThe logon page serves two purposes in a-Expense. It authenticates the user by asking for credentials that are then checked against the password database, and it also copies application-specific user profile information into the ASP.NET's session state object for later use. Examples of profile information are the user's full name, cost center, and assigned roles. The a-Expense application keeps its user profile information in the same database as user passwords, which is typical for applications that use forms authentication.

Note:
Note: a-Expense intentionally uses custom code for authentication, authorization, and profiles instead of using Membership, Roles, and Profile providers. This is typical of legacy applications that might have been written before ASP.NET 2.0.In ASP.NET, adding forms authentication to a Web application has three parts: an annotation in the application's Web.config file to enable forms authentication, a logon page that asks for credentials, and a handler method that validates those credentials against application data. Here is how those pieces work.
The Web.config file for a-Expense enables forms authentication with the following XML declarations:

Code:
<authentication mode="Forms">
     <forms loginUrl="~/login.aspx" 
            requireSSL="true" ... />
</authentication>

<authorization>
    <deny users="?" />
</authorization>


The authentication element tells the ASP.NET runtime (or Internet Information Services, IIS, 7.0 when running both in ASP.NET integrated mode and classic mode) to automatically redirect any unauthenticated page request to the specified login URL. An authorization element that denies access to unauthenticated users (denoted by the special symbol "?") is also required to make this redirection work.
Next, you'll find that a-Expense has a Login.aspx page that uses the built-in ASP.NET Login control, as shown here.

Code:
<asp:Login ID="Login1" runat="server" 
           OnAuthenticate="Login1OnAuthenticate" ... >
</asp:Login>


Finally, if you look at the application, you'll notice that the handler of the Login.aspx page's OnAuthenticate event looks like the following.

Code:
public partial class Login : System.Web.UI.Page
{
  protected void Login1OnAuthenticate(object sender,
                                      AuthenticateEventArgs e)
  {
     var repository = new UserRepository();
     if (!repository.ValidateUser(this.Login1.UserName, 
                                           this.Login1.Password))
     {
         e.Authenticated = false;
         return;
     }
     var user = repository.GetUser(this.Login1.UserName);
     if (user != null)
     {
         Session["LoggedUser"] = user;
         e.Authenticated = true;
     }
  }
}


This logic is typical for logon pages. You can see in the code that the user name and password are checked first. Once credentials are validated, the user profile information is retrieved and stored in the session state under the LoggedUser key. Notice that the details of interacting with the database have been put inside of the application's UserRepository class.
Setting the Authenticated property of the AuthenticatedEventArgs object to true signals successful authentication. ASP.NET then redirects the request back to the original page.
At this point, normal page processing resumes with the execution of the page's Page_Load method. In the a-Expense application, this method retrieves the user's profile information that was saved in the session state object and initializes the page's controls. For example, the logic might look like the following.

Code:
protected void Page_Load(object sender, EventArgs e)
{
    var user = (User)Session["LoggedUser"];
    var repository = new ExpenseRepository();
    var expenses = repository.GetExpenses(user.Id);
    this.MyExpensesGridView.DataSource = expenses;
    this.DataBind();
}


The session object contains the information needed to make access control decisions. You can look in the code and see how a-Expense uses an application-defined property called AuthorizedRoles to make these decisions.

a-Expense with Claims

The developers only had to make a few changes to a-Expense to replace forms authentication with claims. The process of validating credentials was delegated to a claims issuer simply by removing the logon page and by configuring the ASP.NET pipeline to include the Windows Identity Foundation (WIF) WSFederationAuthenticationModule. This module detects unauthenticated users and redirects them to the issuer to get tokens with claims. Without a logon page, the application still needs to write profile and authorization data into the session state object, and it does this in the Session_Start method. Those two changes did the job.
Figure 5 shows how authentication works now that a-Expense is claims-aware.

a-Expense with claims processing
Figure 5
a-Expense with claims processingThe Web.config file of the claims-aware version of a-Expense contains a reference to WIF-provided modules. This Web.config file is automatically modified when you run the FedUtil wizard either through the command line (FedUtil.exe) or through the Add STS Reference command by right-clicking the Web project in Visual Studio.
If you look at the modified Web.config file, you'll see that there are changes to the authorization and authentication sections as well as new configuration sections. The configuration sections include the information needed to connect to the issuer. They include, for example, the Uniform Resource Indicator (URI) of the issuer and information about signing certificates.
The first thing you'll notice in the Web.config file is that the authentication mode is set to None, while the requirement for authenticated users has been left in place.

Code:
<authentication mode="None" />

<authorization>
    <deny users="?" />
</authorization>



Note:
Note: The forms authentication module that a-Expense previously used has been deactivated by setting the authentication mode attribute to None. Instead, the WSFederationAuthenticationModule (FAM) and SessionAuthenticationModule (SAM) are now in charge of the authentication process.The application's Login.aspx page is no longer needed and can be removed from the application.
Next, you will notice that the Web.config file contains two new modules, as shown here.

Code:
<httpModules>
    ...
    <add name="WSFederationAuthenticationModule" 
         type="Microsoft.IdentityModel.Web.
                        WSFederationAuthenticationModule, ..." />

    <add name="SessionAuthenticationModule" 
         type="Microsoft.IdentityModel.Web.
                             SessionAuthenticationModule, ..." />
</httpModules>


When the modules are loaded, they're inserted into the ASP.NET processing pipeline in order to redirect the unauthenticated requests to the issuer, handle the reply posted by the issuer, and transform the user token sent by the issuer into a ClaimsPrincipal object. The modules also set the value of the HttpContext.User property to the ClaimsPrincipal object so that the application has access to it.
The WSFederationAuthenticationModule redirects the user to the issuer's logon page. It also parses and validates the security token that is posted back. This module writes an encrypted cookie to avoid repeating the logon process. The SessionAuthenticationModule detects the logon cookie, decrypts it, and repopulates the ClaimsPrincipal object.
The Web.config file contains a new section for the Microsoft.IdentityModel that initializes the WIF environment.

Code:
<configSections>
...
<section name="microsoft.identityModel" 
         type="Microsoft.IdentityModel.Configuration.
                                MicrosoftIdentityModelSection, 
                                Microsoft.IdentityModel, ..." />
</configSections>


The identity model section contains several kinds of information needed by WIF, including the address of the issuer, and the certificates (the serviceCertificate and trustedIssuers elements) that are needed to communicate with the issuer.

Code:
<microsoft.identityModel>
  <service>
    <audienceUris>
      <add value=
              "https://{adatum hostname}/ a-expense.claimsAware/" 
      />
    </audienceUris>
...



Note:
The value of "adatum hostname" changes depending on where you deploy the sample code. In the development environment, it is "localhost."Security tokens contain an audience URI. This indicates that the issuer has issued a token for a specific "audience" (application). Applications, in turn, will check that the incoming token was actually issued for them. The audienceUris element lists the possible URIs. Restricting the audience URIs prevents malicious clients from reusing a token for a different application that they are not authorized to access.

Code:
<federatedAuthentication>
   <wsFederation passiveRedirectEnabled="true" 
       issuer="https://{adatum host}/{issuer endpoint} "    
       realm="https://{adatum host}/a-Expense.ClaimsAware/" 
       requireHttps="true" />
   <cookieHandler requireSsl="true" />
</federatedAuthentication>


The federatedAuthentication section identifies the issuer and the protocol required for communicating with it.

Code:
<serviceCertificate>
   <certificateReference x509FindType="FindBySubjectDistinguishedName" 
        findValue="CN=adatum" storeLocation="LocalMachine" storeName="My" />
</serviceCertificate>


The service certificate section gives the location of the certificate used to decrypt the token, in case it was encrypted. Encrypting the token is optional, and it's a decision of the issuer to do it or not. You don't need to encrypt the token if you're using HTTPS, but encryption is generally recommended as a security best practice.

Code:
<issuerNameRegistry   
   type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry,  
         Microsoft.IdentityModel, ... >
   <trustedIssuers>
      <add thumbprint="0E2A9EB75F1AFC321790407FA4B130E0E4E223E2" 
           name="CN=adatum" />
   </trustedIssuers>
 </issuerNameRegistry>


A thumbprint is the result of hashing an X.509 certificate signature. SHA-1 is a common algorithm for doing that. Thumbprints uniquely identify a certificate and the issuer. The issuerNameRegistry element contains the list of thumbprints of the issuers it trusts. Issuers are identified by the thumbprint of their signing X.509 certificate. If the thumbprint does not match the certificate embedded in the incoming token signature, WIF will throw an exception. If the thumbprint matches, the name attribute will be mapped to the Claim.Issuer property. 
In the code example, the name attribute adatum is required for the scenario because the a-Expense application stores the federated user name in the roles database. A federated user name has the format: adatum\username.
The following procedure shows you how to find the thumbprint of a specific certificate.

To find a thumbprint
  1. On the taskbar, click Start, and then type mmc in the search box.
  2. Click mmc. A window appears that contains the Microsoft Management Console application.
  3. On the File menu, click Add/Remove Snap-in.
  4. In the Add or Remove Snap-ins dialog box, click Certificates, and then click Add.
  5. In the Certificates snap-in dialog box, select Computer account, and then click Next.
  6. In the Select Computer dialog box, select Local computer, click Finish, and then click OK.
  7. In the left pane, a tree view of all the certificates on your computer appears. If necessary, expand the tree. Expand the Personal folder. Expand the Certificates folder.
  8. Click the certificate whose thumbprint you want.
  9. In the Certificate Information dialog box, click the Details tab, and then scroll down until you see the thumbprint.At this point, you're done. The changes in the Web.config file are enough to delegate authentication to the issuer.
There's still one detail to take care of. Remember from the previous section that the logon handler (which has now been removed from the application) was also responsible for storing the user profile data in the session state object. This bit of logic is relocated to the SessionStart method found in the Global.asax file. The SessionStart method is automatically invoked by ASP.NET at the beginning of a new session, after authentication occurs. The user's identity is now stored as claims that are accessed from the thread's CurrentPrincipal property. Here is what the Session_Start method looks like.

Code:
protected void Session_Start(object sender, EventArgs e)
{
  if (this.Context.User.Identity.IsAuthenticated)
  {     
    string issuer = 
         ClaimHelper.GetCurrentUserClaim(
            System.IdentityModel.Claims.ClaimTypes.Name).
                                                  OriginalIssuer;
    string givenName = 
         ClaimHelper.GetCurrentUserClaim(                             
               WSIdentityConstants.ClaimTypes.GivenName).Value;

    string surname = 
         ClaimHelper.GetCurrentUserClaim(
                 WSIdentityConstants.ClaimTypes.Surname).Value;

    string costCenter = 
         ClaimHelper.GetCurrentUserClaim(
                           Adatum.ClaimTypes.CostCenter).Value;

    var repository = new UserRepository();
    string federatedUsername = 
                  GetFederatedUserName(issuer, identity.Name);
    var user = repository.GetUser(federatedUsername);
    user.CostCenter = costCenter;
    user.FullName = givenName + " " + surname;                

    this.Context.Session["LoggedUser"] = user;
  }
}


Note that the application does not go to the application data store to authenticate the user because authentication has already been performed by the issuer. The WIF modules automatically read the security token sent by the issuer and set the user information in the thread's current principal object. The user's name and some other attributes are now claims that are available in the current security context.
The user profile database is still used by a-Expense to store the application-specific roles that apply to the current user. In fact, a-Expense's access control is unchanged whether or not claims are used.
The preceding code example invokes methods of a helper class named ClaimHelper. One of its methods, the GetCurrentUserClaim method, queries for claims that apply in the current context. You need to perform several steps to perform this query:
  1. Retrieve context information about the current user by getting the static CurrentPrincipal property of the System.Threading.Thread class. This object has the run-time type IPrincipal.
  2. Use a run-time type conversion to convert the current principal object from IPrincipal to the type IClaimsPrincipal. Because a-Expense is now a claims-aware application, the run-time conversion is guaranteed to succeed.
  3. Use the Identities property of the IClaimsPrincipal interface to retrieve a collection of identities that apply to the claims principal object from the previous step. The object that is returned is an instance of the ClaimsIdentityCollection class. Note that a claims principal may have more than one identity, although this feature is not used in the a-Expense application.
  4. Retrieve the first identity in the collection. To do this, use the collection's indexer property with 0 as the index. The object that is returned from this lookup is the current user's claims-based identity. The object has type IClaimsIdentity.
  5. Retrieve a claims collection object from the claims identity object with the Claims property of the IClaimsIdentity interface. The object that is returned is an instance of the ClaimsCollection class. It represents the set of claims that apply to the claims identity object from the previous step.
  6. At this point, if you iterate through the claims collection, you can select a claim whose claim type matches the one you are looking for. The following expression is an example of how to do this.
  7. Finally, you extract the claim's value with the Claim class's Value property. Claims values are strings.

a-Order Before Claims

Unlike a-Expense, the a-Order application uses Windows authentication. This has a number of benefits, including simplicity.
Enabling Windows authentication is as easy as setting an attribute value in XML, as shown here.

Code:
<authentication mode="Windows" />


The a-Order application's approach to access control is considerably simpler than what you saw in aExpense. Instead of combining authentication logic and business rules, a-Order simply annotates pages with roles in the Web.config file.

Code:
<authorization>
   <allow roles="Employee, Order Approver" />
   <deny users="?" />
</authorization>


The user interface of the a-Order application varies, depending on the user's current role.

Code:
base.OnInit(e);

this.OrdersGrid.Visible = 
        !this.User.IsInRole("Order approver");

this.OrdersGridForApprovers.Visible = 
        this.User.IsInRole("Order approver");


a-Order with Claims

Adding claims to a-Order is really just a configuration step. The application code needs no change.
If you download the project from http://claimsid.codeplex.com, you can compare the Web.config files before and after conversion to claims. It was just a matter of right-clicking the project in Visual Studio and then clicking Add STS Reference. The process is very similar to what you saw in the previous sections for the a-Expense application.
The claims types required are still the users and roles that were previously provided by Windows authentication.

Code:
<claimTypeRequired>
  <claimType type=
    "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" 
  />
  <claimType type=
   "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
  />
 </claimTypeRequired>


Signing Out of an Application

The FederatedPassiveSignInStatus control is provided by WIF. Here is how the single sign-on scenario uses it to sign out of an application.

Code:
<idfx:FederatedPassiveSignInStatus 
    ID="FederatedPassiveSignInStatus1" 
    runat="server" 
    OnSignedOut="FederatedPassiveSignInStatus1SignedOut" 
    SignOutText="Logout" 
    FederatedPassiveSignOut="true"   
    SignOutAction="FederatedPassiveSignOut" />


The idfx prefix identifies the control as belonging to the Microsoft.IdentityModel.Web.Controls namespace. The control causes a browser redirect to the ADFS issuer, which logs out the user and destroys any cookies related to the session.

Setup and Physical Deployment

Deploying a claims-aware Web application follows many of the same steps you already know for non–claims-aware applications. The differences have to do with the special considerations of the issuer. Some of these considerations include providing a suitable test environment during development, migrating to a production issuer, and making sure the issuer and the Web application are properly configured for Internet access.

Using a Mock Issuer

The downloadable versions of a-Expense and a-Order are set up by default to run on a standalone development workstation. This is similar to the way you might develop your own applications. It's generally easier to start with a single development machine.
To make this work, the developers of a-Expense and a-Order wrote a small stub implementation of an issuer. You can find this code in the downloadable Visual Studio solution. Look for the project with the URL https://localhost/adatum.SimulatedIssuer.
When you first run the a-Expense and a-Order applications, you'll find that they communicate with the stand-in issuer. The issuer issues predetermined claims.
It's not very difficult to write such a component, and you can reuse the sample that's online.

Isolating Active Directory

The a-Order application uses Windows authentication. Since developers do not control the identities in their company's enterprise directory, it is sometimes useful to swap out Active Directory with a stub during the development of your application.
The a-Order application (before claims) shows an example of this. To use this technique, you need to make a small change to the Web.config file to disable Windows authentication and then add a hook in the session authentication pipeline to insert the user identities of your choosing. Disable Windows authentication with the following change to the Web.config file.

Code:
<authentication mode="None" />


The Global.asax file should include code that sets the identity with a programmer-supplied identity. The following is an example.

Code:
<script runat="server">

void Application_AuthenticateRequest(object sender, EventArgs e)
{
  this.Context.User = MaryMay;
}

private static IPrincipal MaryMay
{
  get
  {
    IIdentity identity = new GenericIdentity("mary");
    string[] roles = { "Employee", "Order Approver" };
    return new GenericPrincipal(identity, roles);
  }
}

</script>


Remove this code before you deploy your application.

Converting to a Production Issuer

When you are ready to deploy to a production environment, you'll need to migrate from your simulated issuer that runs on your development workstation to a component such as ADFS 2.0.
Making this change requires two steps. First, you need to modify the Web application's Web.config file using FedUtil so that it points to the production issuer. Next, you need to configure the issuer so that it recognizes requests from your Web application and provides the appropriate claims.
Appendix A of this guide walks you through the process of using FedUtil and shows you how to change the Web.config files.
You can refer to documentation provided by your production issuer for instructions on how to add a relying party and how to add claims rules. Instructions for the samples included in this guide can be found at http://claimsid.codeplex.com.

Enabling Internet Access

One of the benefits of outsourcing authentication to an issuer is that existing applications can be accessed from the external Internet very easily. The protocols for claims-based identity are Internet-friendly. All you need to do is make the application and the issuer externally addressable. You don't need a VPN.
If you decide to deploy outside of the corporate firewall, be aware that you will need certificates from a certificate authority for the hosts that run your Web application and issuer. You also need to make sure that you configure your URLs with fully qualified host names or static IP addresses. The ADFS 2.0 proxy role provides specific support for publishing endpoints on the Internet.

Variation—Moving to Windows Azure

The last stage of Adatum's plan is to move a-Expense to Windows Azure. Windows Azure uses Microsoft data centers to provide developers with an on-demand compute service and storage to host, scale, and manage Web applications on the Internet. This variation shows the power and flexibility of a claims-based approach. The a-Expense code doesn't change at all. You only need to edit its Web.config file.
Figure 6 shows what Adatum's solution looks like.

Figure 6
a-Expense on Windows AzureFrom Adatum's users' viewpoints, the location of the a-Expense application is irrelevant except that the application's URL might change once it is on Azure, but even that can be handled by mapping CNAMEs to Windows Azure URL. Otherwise, its behavior is the same as if it were located on one of Adatum's servers. This means that the sequence of events is exactly the same as before, when a-Expense became claims-aware. The first time a user accesses the application, he will not be authenticated, so the WIF module redirects him to the configured issuer that, in this case, is the Adatum issuer.
The issuer authenticates the user and then issues a token that includes the claims that a-Expense requires, such as the user's name and cost center. The issuer then redirects the user back to the application, where a session is established. Note that, even though it is located on the Internet, aExpense requires the same claims as when it was located on the Adatum intranet.
Obviously, for any user to use an application on Azure, it must be reachable from his computer. This scenario assumes that Adatum's network, including its DNS server, firewalls, and proxies are configured to allow its employees to have access to the Internet.
Notice however, that the issuer doesn't need to be available to external resources. The a-Expense application never communicates with it directly. Instead, it uses browser redirections and follows the protocol for passive clients. For more information about this protocol, see chapter 2, "Claims-Based Architectures" and Appendix B.

Hosting a-Expense on Windows AzureThe following procedures describe how to configure the certificates that you will upload to Windows Azure and the changes you must make to the Web.config file. These procedures assume that you already have a Windows Azure token. If you don't, see http://www.microsoft.com/windowsazure/getstarted/ to learn how to do this.

To configure the certificates
  1. In Visual Studio, open the Azure project, such as a-expense.cloud. Right-click the a-Expense.ClaimsAware role, and then click Properties.
  2. If you need a certificate's thumbprint, click Certificates. Along with other information, you will see the thumbprint.
  3. Click Endpoints, and then select* HTTPS:. Set the Name* field to HttpsIn. Set the Port field to the port number that you want to use. The default is 443. Select the certificate name from the SSL certificate name drop-down box. The default is localhost. The name should be the same as the name that is listed on the Certificates tab.Note that the certificate that is uploaded is only used for SSL and not for token encryption. A certificate from Adatum is only necessary if you need to encrypt tokens.

Note:
Both Windows Azure and WIF can decrypt tokens. You must upload the certificate in the Windows Azure portal and configure the Web role to deploy to the certificate store each time there is a new instance. The WIF <serviceCertificate> section should point to that deployed certificate.The following procedure shows you how to publish the a-Expense application to Windows Azure.

To publish a-Expense to Windows Azure
  1. In Microsoft Visual Studio 2008, open the a-expense.cloud solution.
  2. Upload the localhost.pfx certificate to the Windows Azure project. The certificate is located at samples-installation-directory\Setup\DependencyChecker\certs\localhost.pfx. The password is "xyz".
  3. Modify the a-Expense.ClaimsAware application's Web.config file by replacing the <microsoft.identityModel> section with the following XML code. You must replace the {service-url} element with the service URL that you selected when you created the Windows Azure project.
  4. Right-click the a-expense.cloud project, and then click Publish. This generates a ServiceConfiguration file and the actual package for Azure.
  5. Deploy the ServiceConfiguration file and package to the Windows Azure project.Once the a-Expense application is deployed to Azure, you can log on to http://windows.azure.com to test it.

Note:
Note: If you were to run this application on more than one role instance in Azure (or in an on-premise Web farm), the default cookie encryption mechanism (which uses DPAPI) is not appropriate, since each machine has a distinct key. In this case, you would need to replace the default SessionSecurityHandler object and configure it with a different cookie transformation such as RsaEncryptionCookieTransform or a custom one. The "Web farm" sample included in the WIF SDK illustrates this in detail..

More Information

Appendix A of this guide gives a walkthrough of using FedUtil and also shows you how to edit the Web.config files and where to locate your certificates.
MSDN® contains a number of helpful articles, including MSDN Magazine's "A Better Approach For Building Claims-Based WCF Services" (http://msdn.microsoft.com/en-us/magazine/dd278426.aspx).
To learn more about Windows Azure, see Windows Azure Platform at http://www.microsoft.com/windowsazure/.

Last edited Jul 7, 2010 at 5:25 AM by eugeniop, version 1

Comments

No comments yet.