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

Contents

Using ADFS for SSO in a Single Organization
Registration, Authentication, and Authorization
Create the ADAM Account Store
Configure the ADFS Server
Configure the IIS Server and Applications
Importing Certificates
Including UnderMyControl.com
Add a Resource Partner
Add an Account Partner
Set Up a New User
Set Up a New Resource
Query for Granted Permissions
Expanding Trust to Tailspin Toys
Looking Forward—Windows Live ID Integration
Summary

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

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.

Figure 2 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.

Figure 3 Web.config File from A. Datum Music Sharing App

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

Figure 4 Required Certificates and Devices

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

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.

Figure 6 Create an Associated Resource

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

Figure 7 Connect Programmatically to UnderMyControl

// 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

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

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.