Printer Friendly Version      Send     
Click to Rate and Give Feedback
Related Articles

Surprisingly, cryptography can be applied to the electoral process to allow every individual voter to check the integrity of an election tally. Find out how here.

Josh Benaloh

MSDN Magazine June 2008

...

Read more!

Here we introduce Microsoft Code Name “Geneva,” the new framework for building claims-based applications and services, and federated security scenarios.

Michele Leroux Bustamante

MSDN Magazine December 2008

...

Read more!

Did you know you can use Windows PowerShell to perform lightweight request/response testing for an ASP.NET Web app? Here's how.

Dr. James McCaffrey

MSDN Magazine May 2008

...

Read more!

Understanding the ACLs that govern permissions and rights before an operation is allowed to proceed is critical to enhancing security.

John R. Michener

MSDN Magazine November 2008

...

Read more!

This month Juval Lowy tackles questions such as when to keep proxies and services in memory for better state management in long-running workflows.

Juval Lowy

MSDN Magazine October 2008

...

Read more!

Popular Articles

Jason Clark

MSDN Magazine July 2003

...

Read more!

The MVP pattern helps you separate your logic and keep your UI layer free of clutter. This month learn how.

Jean-Paul Boodhoo

MSDN Magazine August 2006

...

Read more!

A Sidebar gadget is a powerful little too that's surprisingly easy to create. Get in on the fun with Donavon West.

Donavon West

MSDN Magazine August 2007

...

Read more!

James Avery does it again with his popular list of developer tools. This time he covers the best Visual Studio add-ins available today that you can download for free.

James Avery

MSDN Magazine December 2005

...

Read more!

C# allows developers to embed XML comments into their source files-a useful facility, especially when more than one programmer is working on the same code. The C# parser can expand these XML tags to provide additional information and export them to an external document for further processing. This article shows how to use XML comments and explains the relevant tags. The author demonstrates how to set up your project to export your XML comments into convenient documentation for the benefit of other developers. He also shows how to use comments ...

Read more!

Our Blog

Silverlight and SharePoint provide a simple, yet powerful, infrastructure for building intranet and extranet applications with sophisticated user interface designs and interactions.

In the November 2008 issue of MSDN Magazine, Steve Fox and Paul Stubbs demonstrate how to build a SharePoint Web Part as a wrapper for a Silverlight application.

...

Read more!

With the releases of LINQ to SQL and the ADO.NET Entity Framework, developers now have two products from Microsoft designed to tie together relational data and object-oriented programming.

In the December 2008 issue of MSDN Magazine, Anthony Sneed provides a roadmap to these technologies and demonstrates how you can create ...

Read more!

So many factors can affect the performance of a Web page—the distance between server and client, the size of the elements on the page, how the browser loads these elements, available bandwidth. Finding those bottlenecks and identifying the culprits is no easy task.

In the November 2008 issue of MSDN Magazine, Jim Pierson introduces ...

Read more!

Windows Workflow Foundation (WF) imposes some restrictions on the developer authoring programs that target it. But in return WF offers a powerful, flexible, and extensible set of runtime services such as support for long-running code.

In the December 2008 issue of MSDN Magazine, Josh Lane provides some best practices to consider ...

Read more!

Earlier this year MSDN Magazine embarked on a collaborative project with Behind the Code, an interview program airing on MSDN Channel 9. In this program, Robert Hess interviews prominent developers at Microsoft, and those developers also write a column for { End Bracket } in MSDN Magazine. In the newest interview, Richard Ward talks about working on the core infrastructure components of future versions of Windows, as well as ...

Read more!

Security
Authenticate Users Across Organizations Using ADFS
Jack Couch

This article is based in part on a prerelease version of Windows Live ID. Details herein are subject to change.
This article discusses:
  • Using ADFS for SSO in a single organization
  • Configuring ADFS on the server and client
  • Connecting to an external organization
  • Expanding trust further with ADFS
This article uses the following technologies:
ADFS, ADAM
Active Directory® Federation Services (ADFS) was introduced in Windows Server® 2003 for organizations that need to participate in standards-based identity federation. With ADFS, you can more easily validate identity data from other organizations, leading to greater interoperability with your partners. In this article, I'll take you on a guided tour of ADFS in action, using the experiences of a fictitious online service provider (A. Datum Corporation) that uses ADFS to interact with a real online service provider (UnderMyControl.com) and a fictitious customer (Tailspin Toys).

Using ADFS for SSO in a Single Organization
The A. Datum Corporation is an online service provider that offers two Web applications to consumers. The first Web application enables online document sharing and storage; the second provides online music publishing for independent artists. Rather than using two separate account stores, which would require users to keep track of user names and passwords for each application, A. Datum used ADFS and ADAM (Active Directory Application Mode) to create a single account store, which enables users to access both applications using a single user name and password.
In many situations, an ADFS server will act as either an account partner or a resource partner. An ADFS server acting as an account partner is configured to interact with an account store (either ADAM or Active Directory) to authenticate users. An ADFS server acting as a resource partner is configured to support ADFS-aware applications. In this scenario, the ADFS server provides access both to the applications and to the account store.
By using ADAM in conjunction with ADFS, you can enable single sign-on (SSO) so that customers don't have to remember a multitude of passwords. Figure 1 shows how A. Datum deployed this solution in its organization.
Figure 1 A Single Sign-On Solution 
Note: the Active Directory server is only present because the ADFS server must be domain-joined. Active Directory is not used in this scenario for any other purpose.

Registration, Authentication, and Authorization
When new users sign up with either the file storage or music publishing service, they go through the typical registration process: selecting a user name, setting a password, and providing profile information. This information is then stored in the ADAM account store, allowing that user to authenticate with all applications hosted by A. Datum. Figure 2 shows typical code for connecting to ADAM.
const long ADS_OPTION_PASSWORD_PORTNUMBER = 6;
const long ADS_OPTION_PASSWORD_METHOD = 7;

const int ADS_PASSWORD_ENCODE_REQUIRE_SSL = 0;
const int ADS_PASSWORD_ENCODE_CLEAR = 1;

System.DirectoryServices.AuthenticationTypes AuthTypes =
    AuthenticationTypes.Signing |
    AuthenticationTypes.Sealing |
    AuthenticationTypes.Secure;

// connect to ADAM store
System.DirectoryServices.DirectoryEntry objUsers = new DirectoryEntry(
    "LDAP://10.0.0.212:389/cn=Users,dc=adamstore,dc=com",
    "ADATUM\\administrator","Pa$$word!",AuthTypes);

// create user object
DirectoryEntry user = objUsers.Children.Add(
    "cn="+UsernameTB.Text, "user");

// set user properties
user.Properties["msDS-UserDontExpirePassword"].Value=true;
user.Properties["userPrincipalName"].Value = UsernameTB.Text;
user.CommitChanges();

// set port number, method, and password.
user.Invoke("SetOption", new object[] { ADS_OPTION_PASSWORD_PORTNUMBER, 
    389 });
user.Invoke("SetOption", new object[] { ADS_OPTION_PASSWORD_METHOD, 
    ADS_PASSWORD_ENCODE_CLEAR});
user.Invoke("SetPassword", new object[] { PasswordTB.Text });

Once a user has created an account, when he attempts to access either the file storage or music publishing services the Web server will redirect him to the ADFS server. The ADFS server then prompts the user for his user name and password, communicates with the ADAM server to validate the user's credentials and determine group membership, issues the client a security token, and then redirects the client back to the Web application.
The security token contains information about the user's identity and group membership, which are called claims. The application uses the identity information to verify that the user successfully authenticated to the ADFS server, and it uses the group membership information to make authorization decisions. For example, the music application from A. Datum only allows a user to upload music if the user has the group claim Musicians in the security token:
// check if the user is a Musician and therefore has write (upload)
// permission
if (!User.IsInRole("Musicians"))
{
    // if the user doesn't have permission, show an error message
    Response.Clear();
    Response.Write("You do not have permission to upload files");
    return;
}
If the user now wants to access the other application hosted by A. Datum, he does not need to reenter his credentials. This is because the user already has an ADFS-issued security token that both applications trust. Although A. Datum could have accomplished SSO for its customers by using other techniques, ADFS allows the company to easily expand its trust relationships simply by adding additional account and resource partners.

Create the ADAM Account Store
You must have Windows Server 2003 R2 running on your server and be logged on with local administrator privileges to add the ADAM account store. You create the store by first installing ADAM and then by creating an ADAM instance. Installing ADAM is performed through the Control Panel: select Add/Remove Programs, then Add/Remove Windows Components. Once there, select the Active Directory Application Mode (ADAM) checkbox within Active Directory Services. After ADAM is installed, the All Programs menu within the Start menu will contain a "Create an ADAM instance" item; select this item. When prompted, select a unique instance and a new application directory partition. Once you have created an ADAM instance, you can connect to it using ADAM ADSI Edit. You will need to do this so that you give the account you plan to use the necessary permissions.

Configure the ADFS Server
In order to configure and run ADFS, you must first have IIS installed. You must also use the SelfSSL tool from the IIS 6 Resource Kit (go.microsoft.com/fwlink/?LinkId=36285) to create and install a self-signed SSL server authentication certificate.
The next step is to install ADFS by checking the Federation Service checkbox within Add or Remove Programs. You will be prompted to enable ASP.NET, as this is also needed for ADFS to function. Once installation is complete, the federation service endpoint (the URL for the federation service) and the URI (unique name for the federation service) can be modified with the Active Directory Federation Services snap-in.
Now you can add the ADAM account store. You can do this by right-clicking Account Stores and selecting New. The wizard will ask you for the ADAM server name, the URI (unique name that represents the ADAM store), the search base distinguished name (the location of the user accounts), and the Lightweight Directory Access Protocol (LDAP) attribute used for the user name (generally the userPrincipalName attribute is used).
Claims are user attributes that ADFS will store in the user's security token once the user is authenticated. Group claims indicate membership within a particular group. If a user account in the ADAM account store indicates the user is a member of the Musicians group, the A. Datum ADFS server places the group claim Musicians in the user's security token. Within the Active Directory Federation Services snap-in, right-click Organization Claims and select New Organization Claim. This will launch a wizard and allow you to select the type of claim (Group Claim) and provide the name (Musicians).
You associate the ADAM Musicians group with the Musicians group claim just created by creating a group claim extraction. This is done by right-clicking your account store and selecting New Group Claim Extraction. Here you will specify the LDAP attribute that represents the group membership. For example, you might specify the attribute memberof and the group CN=Musicians, CN=Users,DC=adamstore,DC=com. You will also select the Musicians group claim you just created from a dropdown list.Finally, in order to make the ADFS service aware of the applications for which it will be providing authentication, simply select New Application in the ADFS snap-in and provide the URL of the application.

Configure the IIS Server and Applications
For claims-aware applications, very little configuration is required on the IIS server that's hosting the application. First, you will want to install a server authentication certificate on the IIS server. Again, this can be done using SelfSSL in the IIS 6 Resource Kit. Next, you should install the claims-aware agent within Add/Remove Windows Components. Finally, configure the application to use ADFS for authentication. For a claims-aware application (an application built to use ADFS for authentication), all ADFS-related configuration is done in the app's web.config file. Figure 3 shows the web.config file from the music sharing application by A. Datum.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="system.web">
      <section name="websso" 
        type="System.Web.Security.SingleSignOn.WebSsoConfigurationHandler,
         System.Web.Security.SingleSignOn, Version=1.0.0.0,
         Culture=neutral,
         PublicKeyToken=31bf3856ad364e35, Custom=null" />
    </sectionGroup>
  </configSections>
  
<system.web>
  <sessionState mode="Off" />
  <compilation defaultLanguage="c#" debug="true">
  <assemblies>
    <add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
        PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Design, Version=2.0.0.0, Culture=neutral,
        PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.DirectoryServices, Version=2.0.0.0,
        Culture=neutral,
        PublicKeyToken=B03F5F7F11D50A3A"/> 
    <add assembly="System.Web.Security.SingleSignOn, Version=1.0.0.0, 
        Culture=neutral,
        PublicKeyToken=31bf3856ad364e35, Custom=null"/>
    <add assembly="System.Web.Security.SingleSignOn.ClaimTransforms,
        Version=1.0.0.0,
        Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null"/>
  </assemblies>
  </compilation>
  
  <customErrors mode="Off"/>
  <authentication mode="None" />
  
  <httpModules>
    <add name="Identity Federation Services Application 
        Authentication Module"
        type="System.Web.Security.SingleSignOn.WebSsoAuthenticationModule,
        System.Web.Security.SingleSignOn, Version=1.0.0.0, 
        Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" />
  </httpModules>

  <websso>
    <authenticationrequired />
  
    <urls>
      <returnurl>https://www.adatum.com/Music/</returnurl>
    </urls>
  
    <cookies writecookies="true"> 
      <path>/Music</path>
    </cookies>

    <fs>https://adatum.ad.adatum.com/adfs/fs/
        federationserverservice.asmx</fs>
  </websso>
</system.web>

<system.diagnostics>
  <switches>
    <add name="WebSsoDebugLevel" value="255" />
  </switches>

  <trace autoflush="true" indentsize="3">
    <listeners>
      <add name="LSLogListener" 
        type="System.Web.Security.SingleSignOn.BoundedSizeLogFileTrace
        Listener, System.Web.Security.SingleSignOn, Version=1.0.0.0, 
        Culture=neutral,
        PublicKeyToken=31bf3856ad364e35, Custom=null"  
        initializeData="c:\logdir\claimapp.log" /> 
    </listeners>
  </trace>
</system.diagnostics>

</configuration>

There are several areas of interest within Figure 3. Note the <configSections> block. The section name websso specifies the ADFS SSO.dll so it can be loaded by ASP.NET. The <assemblies> section lists several items, including the SingleSignOn and ClaimTransforms assemblies that ADFS uses.
The module declared in the httpModules section intercepts all HTTPS requests in order to validate the authentication by ensuring it is signed by the resource federation service. If a valid authentication cookie is not present, this httpModule will redirect the client to the federation service for authentication.
In the <websso> section, notice the <authenticationrequired/> tag. If this is not present, anonymous access to the site will be allowed and it is up to the individual page events to validate the security token before granting access. The HTTPmodule will still validate the authentication cookie, but it will not redirect the client to the federation service if a valid authentication cookie is not presented.
The <urls> section lets you specify the URL used by the ADFS server to redirect the client back to the application after the client has been authenticated. It's also used to identify the application when redirecting clients to the ADFS server. This must end with a forward slash (/):
<urls>
<returnurl>https://www.adatum.com/Music/</returnurl>
</urls>
The <cookies> section is used by ADFS to store the security token issued by the ADFS server on the client:
<cookies writecookies="true">
<path>/Music</path>
</cookies>
Finally, the <fs> tag specifies the location of the federation service URL so that the application can successfully authenticate user requests.

Importing Certificates
Because we are using self-signed certificates for A. Datum, we need to install certificates into the trusted root store for all the clients and most of the servers in use. This can be avoided by only using certificates issued by certificate authorities already installed in the trusted root store. You add certificates to the trusted root store using the Certificates Microsoft Management Console (MMC) snap-in. Figure 4 lists the clients, servers, and certificates that need to be installed using this procedure.

Device Type Certificates Required
Web application servers (IIS) Token signing certificate of the organization's ADFS service. Server authentication certificate of the organization's ADFS servers.
Client computers Token signing certificates for all ADFS services. Server authentication certificates for all ADFS servers and Web application servers.
Resource ADFS servers Token signing certificates for all account partner ADFS services.

Including UnderMyControl.com
Release 1.0 of the applications from A. Datum had very simple access control requirements. For the music publishing application, users were either musicians or fans. Musicians could upload music and everyone else could download all the music available. Simple access requirements were also needed for the file storage application. Either you were allowed to upload and download documents or you were only allowed to download documents.
With release 2.0 of these services, A. Datum wanted to greatly expand the access control capabilities of the file-sharing app and allow the owner of a document to assign specific permissions to other users. For example, if Bob was the owner of a specific document, he would be able to assign read permissions to Sue and read/write permissions to Tom. This would typically require that A. Datum rewrite much of the application logic and create a lot of new UI elements, but, because the company was already using ADFS, it decided to outsource its access control management needs to Web services provided by UnderMyControl.com to allow users to manage discretionary access control lists on resources.
As you can see in Figure 5, UnderMyControl.com also uses ADFS, but in this case to grant access to its application. By adding A. Datum as a trusted account partner on the UnderMyControl.com ADFS server and adding UnderMyControl.com as a trusted resource partner on the A. Datum ADFS server, A. Datum users can access UnderMyControl.com with the security token issued by A. Datum. In other words, they do not have to log in to UnderMyControl.com with a separate user name and password.
Figure 5 Outsourcing Access Control Management 

Add a Resource Partner
In order to establish the necessary trust relationship, A. Datum added UnderMyControl.com as a resource partner. This is done with the ADFS MMC snap-in by right-clicking Resource Partners and selecting New Resource Partner. From within the wizard you will need to provide the URL of the UnderMyControl.com ADFS service and select Federated Web SSO (indicating that no Active Directory trusts are involved).

Add an Account Partner
After configuring the A. Datum ADFS server with UnderMyControl.com as a resource partner, the trust relationship is completed by adding A. Datum as an account partner on the UnderMy Control.com ADFS server. This is done by right-clicking Account Partners and selecting New | Account Partner. Here you will need to provide the URL of the A. Datum ADFS service and select Federated Web SSO. You will also need to provide the token signing certificate used by A. Datum when creating security tokens your ADFS service will trust.

Set Up a New User
Although the user accounts are located in the A. Datum ADAM account store, UnderMyControl.com still needs to be aware of all users to allow other users to grant each other permissions. This is accomplished by creating a user profile in UnderMyControl.com using the Web service. When creating a user that will be authenticated via ADFS, don't provide a password:
// connect to Under My Control web service
umc.Service svc = new umc.Service();
svc.CookieContainer = new System.Net.CookieContainer();
Session["CookieContainer"] = svc.CookieContainer;

// create a new UMC user
System.Guid userGuid;
svc.CreateAccount(UsernameTB.Text, "", "" , out userGuid);
Because UnderMyControl.com allows users to manage permissions on resources, it needs a profile for each user that can be granted access and that can grant access to other users; however, the A. Datum account (user name and password) is stored exclusively in the ADAM server of A. Datum.

Set Up a New Resource
When a new document or song is uploaded to one of the A. Datum applications, the app creates an associated resource in UnderMyControl.com and sets the default permissions using the UnderMyControl.com Web service, as shown in Figure 6.
// connect to the Under My Control web service
umc.Service svc = new umc.Service();
svc.CookieContainer = 
    (System.Net.CookieContainer)Session["CookieContainer"];

// guid for the Under My Control music project
Guid projectGuid = new Guid("5f2739ff-a441-44fd-8c68-545a6d654e69");

// guid for the newly created resource
Guid resourceGuid;
                
// create new resource with name set to uploaded file name               
svc.CreateResource(FileUpload.FileName, projectGuid, out resourceGuid);

// Set the permissions for the resource
// add the user as an owner of the new resource
svc.AddOwnerToObject( (Guid)Session["User_GUID"], resourceGuid);

// UMC permission ids for this project
const int READ_PERMISSION = 13;
const int WRITE_PERMISSION = 14;

// give user read (aka download) and write permissions
svc.CreateACL( (Guid) Session["User_GUID"], resourceGuid, 
    READ_PERMISSION);
svc.CreateACL( (Guid) Session["User_GUID"], resourceGuid, 
    WRITE_PERMISSION);


Query for Granted Permissions
When any user attempts to access a document or song, the A. Datum application first queries for that user's granted permissions in the UnderMyControl service and then only allows those actions. Figure 7 shows how you would perform authorization on a resource.
// connect to the Under My Control web service
umc.Service svc = new umc.Service();
svc.CookieContainer = 
    (System.Net.CookieContainer)Session["CookieContainer"];

// ID for WRITE_PERMISSION in UMC for this project
const int WRITE_PERMISSION = 14;

// check if the user has write permissions for the resource in UMC
bool hasPermission = false;
if(!svc.HasACL((Guid)Session["User_GUID"], resourceGuid, 
    WRITE_PERMISSION, out hasPermission)||!hasPermission)
{
    // if the user doesn't have permission, show an error message
    Response.Clear();
    Response.Write(
        "You do not have permission to overwrite this file");
    return;
}


Expanding Trust to Tailspin Toys
After version 2.0 of the file-sharing app was released with enhanced access control, consumer interest soared, but so did corporate interest. To the surprise of A. Datum, the company found itself in an agreement to provide document management to a large toy maker, Tailspin Toys. Tailspin wanted to use the A. Datum document storage application to allow employees anytime access to documents and to share them with colleagues, partners, and customers. However, Tailspin did not want to ask each of its employees to create a user account with A. Datum and maintain another user name and password. Again, the solution was ADFS.
A. Datum added Tailspin Toys as an account partner, allowing its employees to access A. Datum applications using their Tailspin Toys security tokens, as shown in Figure 8. The procedures for establishing the account and resource partner relationships on the A. Datum ADFS server and on the Tailspin Toys ADFS server are the same as those used to establish the trust relationship with UnderMyControl.com.
Figure 8 Tailspin Toys and A. Datum Implementation 
Of course, for the purposes of this discussion, Tailspin Toys has an oversimplified deployment. In a real deployment, an Account Federation Server Proxy would be used as an intermediary between the internal corporate network containing the Active Directory server and the external-facing ADFS server. For more information on using Account Federation Server Proxies, see the ADFS Design and Deployment Guide on the TechNet Web site.

Looking Forward—Windows Live ID Integration
Tailspin Toys proved to be the first of many organizations that outsourced document management to A. Datum with the same ADFS configuration. But as A. Datum continued to grow, it learned that many of its customers were small businesses using Office Live to host their employee accounts. The company also learned that many of its non-business users already had Windows LiveTM ID accounts. Because Windows Live ID is slated to support ADFS in the future, A. Datum realizes that both of these groups of users could eventually have the ability to use their existing user accounts by simply adding Windows Live ID as another account partner. Figure 9 shows a completed setup.
Figure 9 A. Datum and Windows Live ID Implementation 
Using Windows Live ID as an account partner is not currently supported. The Microsoft Active Directory Federation Services product team and the Microsoft Windows Live ID team are currently developing a strong integration capability to enable various scenarios such as the one listed in this section. This integration work will be enabled as part of future releases of both ADFS and the Windows Live ID service.

Summary
Thanks to ADFS, A. Datum enjoyed greater flexibility in extending trust relationships to other organizations. This allows A. Datum to provide a more user-friendly experience by reducing the hassle of creating and maintaining multiple user accounts.

Jack Couch started his career in military intelligence and spent the past decade providing information security expertise to high-security government agencies and Fortune 500 companies. Recently, Jack was the Security Release Manager for Microsoft Windows Vista. He is currently the Managing Partner at DeepIntel, a security consulting firm dedicated to improving the security of large organizations. Jack can be contacted at jack@deepintel.com.

Page view tracker