Active Directory

Understanding Proxy Authentication in AD LDS

Ken St. Cyr

 

At a Glance:

  • Defining proxy authentication
  • Why proxy authentication is useful
  • Inside the proxy object
  • What happens during authenticationItem

Contents

What Is Proxy Authentication?
Benefits of Proxy Authentication
Inside the Proxy Object
How the Authentication Is Actually Performed
Setting up a Proxy Authentication Lab
Conclusion

As with any LDAP-enabled directory service, Microsoft Active Directory Lightweight Directory Services (AD LDS—formerly called ADAM) requires a user to bind before executing any LDAP operations against the directory. This bind can be done through a few different methods, including a simple LDAP bind, a Simple Authentication and Security Layer (SASL) bind, or even bind redirection. The bind could also be anonymous, in which case the user presents a null password. In this article, I am going to discuss and analyze one method specifically—bind redirection, otherwise known as proxy authentication.

What Is Proxy Authentication?

Proxy authentication allows a user to perform a simple bind to an AD LDS instance, while still maintaining an association to an Active Directory account. Two accounts are involved in the transaction. The first is a special object in AD LDS called a userProxy object. The second is the user's account in Active Directory.

The AD LDS userProxy object is a representation of the Active Directory account. The proxy object is tied to the Active Directory account through that account's security identifier (SID). There is no password stored on the actual proxy object itself.

When a user performs a simple bind to an LDS instance with a proxy object, the bind is redirected to Active Directory by passing the SID and password to a domain controller. The AD LDS server performs the authentication, and the entire process is invisible to the end user. This is illustrated in Figure 1, where Lucy is connecting to an AD LDS instance called "CN=AppDir,DC=contoso,DC=com" with her AD LDS user account.

fig01.gif

Figure 1 Connecting with AD LDS (Click the image for a larger view)

For the authentication, Lucy is using a simple bind, and she supplies her distinguished name (DN) and password as she would during a normal LDAP bind. Although Lucy seemingly connects with her typical LDS user account, she is actually using a proxy object. The authentication to Active Directory is happening behind the scenes, and Lucy has no clue that she's actually using her Active Directory account to bind.

Benefits of Proxy Authentication

The power of proxy authentication lies in giving application developers access to a user object without giving them access to the Active Directory account. Consider what happens when a new directory-enabled application is being built and the application needs to store some data in Active Directory. The application can either use an existing attribute or create a new one.

The danger in using an existing unused attribute is that the attribute is likely there for another purpose. Even if it's unused now, it could be used in the future; if it's used for some different purpose, the Active Directory administrators would have to keep track of how it's being used. And what if the app developer needs more than one attribute?

With proxy authentication, a representation of the Active Directory user object exists in the AD LDS directory. An application-specific directory allows the application developer to modify the schema any way he'd like in the context of AD LDS. Attributes can be added, changed, or repurposed in any manner the developer chooses, and the Active Directory administrator doesn't have to worry about making multiple schema changes or keeping track of how attributes are used. If another application comes online and wants to use the same attribute, it's not a problem because it can be a separate AD LDS instance and won't have any attribute conflicts.

Proxy authentication can also be useful in situations that require the X.500 format. Active Directory does not use typical X.500 nomenclature for DNs. For example, a user object in Active Directory has the DN "CN=Lucy D. Smith,CN=Users,DC=contoso,DC=com". However, in AD LDS, the user's DN could be "CN=Lucy D. Smith,CN=Users,O=Contoso,C=US", which is compatible with X.500.

This is helpful when you're using a third-party LDAP client or trying to integrate with a third party directory that requires the X.500 format. In this way, LDS can be an intermediary directory between a third-party directory and Active Directory. Using proxy authentication, the service account that the third-party directory needs to use to bind to the LDS instance can be held in Active Directory instead of LDS itself.

Inside the Proxy Object

So far I've given a brief overview of how the LDS proxy object is tied to the Active Directory user account. I'll now look at this in more detail and examine what's actually happening behind the scenes, starting with the object class.

In Windows Server 2008, the %SYSTEMROOT%\ADAM directory contains two LDF files that represent a proxy object:

  • MS-UserProxy.LDF
  • MS-UserProxyFull.LDF

MS-UserProxy.LDF holds the definition for the simple userProxy class, which has basic attributes and contains the msDS-BindProxy auxiliary class. MS-UserProxyFull.LDF contains the msDS-BindProxy auxiliary class as well, but it also pre-populates additional user attributes into the mayContain attribute of the class. Because of this, the attribute classes have to exist beforehand. So when importing the userProxyFull class, either the user or inetOrgPerson class needs to be imported first. Both user and inetOrgPerson contain the attribute class definitions for the attributes that userProxyFull uses. Figure 2 shows the differences between the userProxy class and the userProxyFull class.

fig02.gif

Figure 2 The userProxy and userProxyFull classes (Click the image for a larger view)

The fact that both classes contain msDS-BindProxy as an auxiliary class is significant. An auxiliary class is a type of class that can provide additional data to a structural class. In LDS, for example, the User class is a structural class that is inherited from the Organizational-Person class, which means that the User class has everything that the Organizational-Person class has. But the User class also has an auxiliary class called msDS-BindableObject, which means User contains all of the mandatory and optional attributes of msDS-BindableObject in addition to the attributes from the Organizational-Person class. In this instance, using msDS-Bindable­Object as an auxiliary class makes the User class bindable.

Since the userProxy class has msDS-BindProxy as an auxiliary class (see Figure 3), it now also contains the entire mandatory and optional attribute set of msDS-BindProxy. The msDS-BindProxy auxiliary class is what turns an object into a proxy object. So even if you have a custom class, you can add the msDS-BindProxy auxiliary class and use your custom objects for proxy authentication.

fig03_L.gif

Figure 3 Creating a proxy object (Click the image for a larger view)

If you were to examine the msDS-BindProxy class, you would notice that there is only one mandatory attribute defined—objectSID. This is the attribute that the SID of the Active Directory user account will be placed in to create the association between the proxy object in LDS and the user object in Active Directory. This attribute can only be populated when the object is created. It cannot be changed without deleting the object and recreating it.

How the Authentication Is Actually Performed

To truly understand what's happening behind the scenes, we'll need to go a little bit deeper into how the authentication is performed. I'll walk through two network traces that will help show how proxy authentication works. The first trace is a network capture of a proxy user's simple bind from a Windows XP workstation to a Windows Server 2008 LDS instance. In this capture, Lucy binds with her proxy user object using LDP.EXE from her workstation.

Figure 4 shows the three packets in the capture that we need to examine. Packet 1 is the bind request from the workstation (10.0.0.107) to the Active Directory LDS server (10.0.0.201). The bind request contains Lucy's DN, "cn=lucy,cn=people,cn=appdir,dc=contoso,dc=com". Packet 2 is the response from the Active Directory LDS server to the workstation, indicating a successful bind. And packet 3 is the acknowledgment from the workstation to the Active Directory LDS server, indicating the acknowledgment of the bind response.

fig04.gif

Figure 4 Bind request and response (Click the image for a larger view)

If you dig into the details of packet 1 (see Figure 5), you'll notice something shocking. The password that Lucy supplied (P@ssw0rd) is displayed in clear text in the capture. This is, in fact, one of the downfalls of using a simple LDAP bind for authentication. Unless the bind is wrapped in SSL encryption, the user's password will be advertised to anyone listening on the network.

fig05.gif

Figure 5 Simple bind with SSL turned off (Click the image for a larger view)

Active Directory LDS does enable SSL by default, however. You have to go out of your way to turn it off, which is exactly what I did for this exercise in order to make the network trace readable. And I didn't bother to assign a certificate to the Active Directory LDS server, but in an actual implementation, you absolutely want to ensure that the Active Directory LDS server has a valid certificate that can be used for SSL.

The second trace is a network capture from the Active Directory LDS server to the domain controller (DC). This trace is a bit larger than the first one, so I'll break it up into chunks. The first 9 packets of this trace are shown in Figure 6.

fig06.gif

Figure 6 AD LDS connecting to the domain controller (Click the image for a larger view)

The first packet should look familiar to you. This is in the incoming bind request from the workstation. Again, this packet contains Lucy's DN and password in clear text. Packets 2 through 9 show the AD LDS server (10.0.0.201) connecting to the domain controller (10.0.0.200). This consists of some address resolution protocol (ARP) messages followed by a remote procedure call (RPC) connection to the DC.

In Figure 7, packets 10 and 11 call a method named LsarLookupSids3, an RPC call that tells the DC to take a batch of SIDs and return their corresponding names. The AD LDS server makes the request in packet 10 and receives the response from the DC in packet 11.

fig07.gif

Figure 7 Kerberos authentication attempt (Click the image for a larger view)

Then, after a brief TCP handshake to start the Kerberos session (packets 12–14), in packet 15 the AD LDS server attempts to get the authentication service ticket (AS-REQ) from the Key Distribution Center (KDC). In packet 16, the authentication service ticket request is denied because the DC is expecting some pre-authentication data that the AD LDS server didn't provide. In this case, the DC wants the timestamp so it can be used for identity verification. The Kerberos session ends and a reset is requested (packets 17–19).

Figure 8 shows the rest of the capture. Packets 20–22 establish a new Kerberos session and a new authentication service request is sent from the AD LDS server to the DC in packet 23. This new request contains the necessary pre-authentication data, indicated by the successful reply from the DC in packet 25. The AD LDS server now has the authentication service ticket and can place a request to the ticket granting service to authenticate Lucy's credentials.

fig08.gif

Figure 8 Successful authentication (Click the image for a larger view)

The ticket granting service request and response are captured in packets 33 and 34. The receipt of the KRB_TGS_REP in packet 34 indicates that Lucy is successfully authenticated. Finally, in packet 38 the AD LDS server passes the bind response back to the workstation, letting Lucy know that she has successfully bound to the AD LDS instance. Although this process involves several steps, the total time for this entire transaction is only about 1/10th of a second.

What would happen if Lucy entered the wrong password? In our example, the authentication service request would fail at packet 25. The failure of the authentication service request would tell the AD LDS server that Lucy's credentials were bad. Instead of issuing a request to the ticket granting service, the AD LDS server would issue a bind response back to the workstation, stating that the credentials were invalid.

Here is a recap of what happened in the successful exchange:

  1. The workstation sends a bind request to the AD LDS server.
  2. The AD LDS server establishes a connection with the DC.
  3. The AD LDS server asks the DC to translate Lucy's SID into an identifier that it can use for authentication.
  4. The DC gives the AD LDS server Lucy's ID.
  5. The AD LDS server gets a ticket granting ticket (TGT) from the DC with Lucy's ID.
  6. The AD LDS server gets a session ticket to itself using Lucy's TGT.
  7. The AD LDS server sends a successful bind response back to the workstation.

This process shows that the connection from the workstation to the AD LDS server is a standard LDAP bind transaction. Then from the AD LDS server to the DC, Kerberos is used to securely authenticate the user.

Setting up a Proxy Authentication Lab

Now that you know how proxy authentication works, let's see how you can set this up in a lab environment. Note that for this exercise, I'll be disabling the requirement for SSL in proxy authentication. As I mentioned earlier, however, please remember that you should not disable this requirement in a real-life implementation.

Before you start, you will need a fully functional domain with a Windows Server 2008 member server and a workstation joined to it. The Windows Server 2008 member server will run AD LDS, and the workstation will be the client endpoint. The advantage in separating these computers is that you can take network captures of the interaction between them. To set up the lab, I'll walk you through the following steps:

  • Install AD LDS on the member server.
  • Disable the SSL requirement for proxy authentication.
  • Import the userProxy class into the AD LDS schema.
  • Create the proxy object and assign permissions to it.
  • Bind to the AD LDS directory with the proxy object.

The first step is to install AD LDS on the Windows Server 2008 member server. In the Server Manager, you will find the option to install LDS in the "Add Roles" wizard. After the role is installed, a new option will appear in the Administrative Tools menu called Active Directory Lightweight Directory Services Setup Wizard. Use this wizard to create a new LDS instance.

When prompted for the name of the application partition, enter any DN you'd like. Remember that LDS supports X.500 naming, so you're not limited to using a "DC=" style name. In my examples, I used "cn=appdir,dc=contoso,dc=com", but I could have also used "cn=appdir,o=contoso,c=us".

After the AD LDS instance is installed, the next step is to disable the SSL requirement for proxy authentication. In the ADSI Edit snap-in (adsiedit.msc), you should connect to the configuration partition of the AD LDS instance using the administrator account you specified during the install. If you don't know the DN of the configuration partition, you can choose "Configuration" from the "Select a well known naming context" dropdown list in the connection settings dialog in ADSI Edit.

Browse to the container "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,CN={guid}" and bring up the properties dialog of the "CN=Directory Service" container. There is a multi-value string attribute in the attribute list called msDS-Other-Settings that lists multiple strings, each indicating a different setting for the AD LDS instance. Edit this attribute and change the string "RequireSecureProxyBind" to a value of 0.

The next step is to import the schema class definition for the userProxy class. You may have already imported it when prompted to do so in the AD LDS wizard. If so, you can skip this step. If you did not already import it, do so with the following LDIFDE.EXE command. Ensure that you specify the name of the AD LDS server and the correct port in the command:

C:\> ldifde –i -f c:\windows\adam\ms-userproxy.ldf –s
   server:port –k –j . –c 
   "cn=schema,cn=configuration,dc=X"
   #schemaNamingContext

Now that the object class has been imported, the proxy object can be created. I'll use LDP.EXE, but you could use another tool or some programmatic method. Using LDP, connect to your AD LDS instance and bind with your administrator credentials. Browse to the DN of your AD LDS instance and then choose the container in which you want to create the proxy object. Right-click on the container and choose Add Child from the dropdown list. In the Add dialog, you will need to enter the DN of the new proxy object in the DN field. For example, you can use "cn=lucy,cn=appdir,o=contoso,c=us".

You'll also need to create two attributes with this object. The first is objectClass, which indicates the kind of object being created. The value for this example should be userProxy. Put this information in the Edit Entry section of the dialog and click the Enter button.

The second attribute to add is objectSID, which contains the SID of the Active Directory user account with which this proxy object is associated. You can obtain this SID with a variety of methods, but I just connected to Active Directory in a separate LDP instance and copied the objectSID attribute from the user account there. After entering this information, the Add dialog should be similar to Figure 9. Finally, click the Run button to commit the change.

fig09.gif

Figure 9 Creating a proxy object

In order to use the proxy object you just created, you'll need to give it some permissions. You can accomplish this easily by selecting the "CN=Readers" object under the "CN=Roles" container in LDP. Right-click and choose Modify from the dropdown list. Add an attribute called member and for the value, enter the DN of the userProxy object you created. Remember to click the Enter button before clicking Run. Now the userProxy object should be a member of the Readers group in the LDS instance.

Everything should be set up, so you can now test the proxy authentication. Open a new instance of LDP and connect to the AD LDS server. This time, however, when you bind to your instance, select Simple Bind and type in the DN of the proxy object in the user name field. For the password, enter the password of the Active Directory account you tied this proxy object to. Click OK and you should now be bound to the instance in read-only mode.

Spend some time taking network traces and trying out different bind methods. One exercise might be to turn SSL back on and take a capture of the LDAP bind process then. You could even purposely mistype a user name or password and see what happens to the authentication process.

Conclusion

Don't be alarmed over the difficulty of using proxy authentication. I took the approach of demonstrating this process with LDP and ADSI Edit because it gives you a better look behind the scenes. Because of that, the example I walked you through here illustrates proxy authentication from a very hands-on perspective.

In practice, the lengthy process of creating userProxy objects and manipulating them is usually codified through an identity management system or a custom-developed front end for creating accounts. I encourage you to build your own LDS lab and see for yourself how you can use proxy authentication for integrating your third-party directories and applications.

Ken St. Cyr is a consultant for Microsoft and has designed and implemented directory solutions based on Active Directory since its inception. He recently became one of the first to achieve the Microsoft Certified Master certification for Directory Services. Contact him at ken.stcyr@microsoft.com.