Azure Active Directory Connect – Behind The Scenes – Part 3

Hello once again and welcome back. This post will conclude my deep dive into Azure Active Directory Connect. Today we will cover how Azure Active Directory Sync (AADS) reaches out to Azure Active Directory (AAD), how the authentication occurs, and what the communication between the two looks like. For this exercise we’ll be using Fiddler to take a deeper look at the traffic.

To capture the traffic between AADS and AAD the machine.config in C:WindowsMicrosoft.NETFramework64v4.0.30319Config needs to be modified to according to this link. After the section below is added, open Fiddler and save the new config and execute a manual initial sync of AADS through PowerShell.

After the sync finishes, we see the sessions captures below.


Let’s break down the process.

  1. The application performs an GET for Within the header we are requesting home realm discovery on the identity being used to connect to Azure Active Directory, This identity is automatically provisioned in your Azure Active Directory instance during the configuration of Azure Active Directory Connect.The browser is returned a JWT that includes the following information:
    1. account_type=Managed – Indicates the account is an Azure AD Managed account
    4. ver=1.0
  2. The application next performs a POST to which is the authorization server endpoint for my sample tenant. The following names and values are posted:
    1. Resource = – Access to Azure Graph API is being requested.
    2. client_id Your instance of AADC’s client ID that was automatically created during installation
    3. grant_type = password – Indicates Resource Owner Credentials flow is being requested.
    4. username = – UPN of the AADC account
    5. password – This is a 16 character complex password that was automatically configuring during configuration of AADC. Recall that 16 characters is currently the maximum password length for an Azure AD Managed account.
    6. scope = openid – Here we are requesting OpenID Connect 1.0.

    After our account has been successfully authenticated, we are returned a JWT containing a bunch of information. Let’s take some time and break down the data returned.

    1. access_token – Here we receive back a signed bearer access token that has been issued by my tenant’s token endpoint that includes the claims of the IP address of my AADC server, an audience of the graph API, an authentication method reference indicated we authenticated with a password, the name of the account we authenticated with from Azure AD (actual name, not the UPN), the UPN, and a scope of user impersonation.
    2. expires_in = 3600 – This indicates the access token has a lifetime of 60 minutes.
    3. expires_on = some value – The time the token expires. This value is the number of seconds from epoch.
    4. ext_expires_in = 3600 – I’m not sure what this value is indicating the expiration time for.
    5. id_token – This is an id token that contains similar information about the identity as the access token. This is not signed.
    6. not_before = some value The time after which the bearer token can be used. This value is the number of seconds from epoch.
    7. refresh_token – Our apps refresh token.
    8. resource =
    9. scope = user_impersonation – Indicates the scope of the access token we received is user impersonation.
    10. token_type = bearer – Indicates the access token we received is a bearer token.
  3. The application next performs a POST to and begins to communicate with SOAP provisioning API. That’s correct, I said SOAP. I’m unsure as why MS is using the SOAP instead of the REST-based Graph API. Maybe it’s a legacy thing they are still in the progress of migrating? I won’t spend much time digging into what the communication content looks like because I don’t think it lends a ton of value.

The authentication process outlined in steps 1 and 2 are repeated regardless of whether Azure AD Sync is performing an import or an export. There is some interesting differences in the SOAP calls that I want to call out. During the import/export we see the following calls being made to the API:

  1. ReadBackAzureADSyncObject
  2. GetCompanyConfiguration
  3. UpdateDirSyncConfiguration
  4. ProvisionAzureADSyncObjects
  5. FinalizeExport

My guess is the first two calls are performed during and import run profile and the last three are performed during an export run profile.

Well folks that is it for today. I hope your inner geek has been satisfied by taking a look behind the “magic” Microsoft loves so much these days.

Thanks for reading!

Attribute Uniqueness in Azure Active Directory

As I dive deeper into Azure Active Directory, I am learning quickly that AAD is a very different animal than on-premises Active Directory Domain Services (AD DS). While both solutions provide identity, authentication, and authorization services, they do so in very different ways. These differences require organizations to be prepared to adjust standard processes to get the two services to work together. Today I will focus on the identity portion of the solution and how the different attribute uniqueness requirements in AAD and AD DS can introduce the need for evolution of management processes for AD DS.

The attributes I want to focus on are userPrincipalName, proxyAddresses, and mail. In AD DS userPrincipalName is a single valued attribute, proxyAddresses is a multivalued attribute, and the values included in those attributes must be unique to the object in the forest. The mail attribute (the attribute that populates the E-mail field on the General tab of Active Directory Users and Computers (ADUC)) is a single valued attribute that doesn’t have a uniqueness requirement. In AAD all three attributes retain their single value or multivalued properties, however, the uniqueness requirements change considerably.

AD DS allows these values to be duplicated across different attributes. For example, one object could have a userPrincipalName of and another object could have a value in its proxyAddresses attribute of The same goes for an object that has a mail attribute of and another object has a value in its proxyAddresses of

In AAD this is no longer true. User, group, and contact objects synchronized to AAD from AD DS require the userPrincipalName, proxyAddresses, and mail (also targetAddresses if you’re using it) to be unique among all objects in the directory. This means that each of the scenarios I discussed above will create synchronization errors. You can’t have one user object with a value in the proxyAddresses of and another use object with mail attribute of

What happens if you do? Well, let’s make it happen. In this scenario we have two user objects with the configuration below:

Object 1
Sync Status: Already synced to Azure AD

Object 2
Sync Status: Not yet synced to Azure AD

After we force a delta synchronization of Azure AD Sync, the errors provided below pop up in Synchronization Manager and an email alert:



The net result of the above won’t synchronize correctly to AAD and the user will be unable to authenticate to AAD. How about two user objects with the same mail attribute? That’s a common use case, right? Nope, same issue. Take note that just because you receive an error saying the issue is with a duplicate value in the proxyaddresses attribute, it could be the userPrincipalName, mail, or targetAddress of another object in AD DS.

Small differences like this can lead to major changes in how organizations manage AD DS when they begin their journey into AAD. The key take away here is to understand that AD DS and AAD are not the same thing, the differences need to be understood, and you must be prepared to evolve existing processes if you wish to leverage the solution.

I’ll end this with a thank you to Jimmie Lightner from MS for his blog post that brought light to this issue many months ago. You can read that post here.

P.S. Take note that if you opt to an alternate login ID (separate attribute from userPrincipalName for user identifier in AAD), the uniqueness will carry over to that attribute as well.

Azure Active Directory Connect – Behind The Scenes – Part 2

Today I will continue my series of blog posts on Azure Active Directory Connect. In today’s entry I will cover the database backend that powers the Azure Active Directory Sync portion of the AADC solution.

AADC supports both a full-fledged version of SQL running on a dedicated server or a localized database that is installed automatically during the initial installation. The decision as to which to use depends on the number of objects in the on-premises Active Directory environment that AADC will synchronize from. I will focus in on the localized database.

My first assumption was that Microsoft would use a Windows Internal Database (WID) solution for the backend, as they do with server roles like Active Directory Federation Services (AD FS) and Active Directory Rights Management Services (AD RMS). Instead Microsoft has chosen to use a version of Microsoft SQL server called Microsoft SQL Express LocalDB. You can think of LocalDB as the middle ground between MS SQL Compact and MS SQL Express in terms of functionality and use case.

So we know the version of SQL, but how do we connect to it? Is it a named instance?

Try as I may I could not find an Azure AD Connect PowerShell cmdlet that provided me with the connection string information. My next stop was the registry. As luck may have it, I found the information in HKLMSYSTEMCurrentControlSetServicesADSyncParameters as seen in the screenshot below.


The registry keys we are interested in are the Server, SQLInstance, and DBName. These entries indicate that the instance is running on the local server, the instance name is ADSync, and the database is named ADSync. This provides enough information to connect to the database using SQL Management Studio. We’ll use this string (localdb).ADSync to connect to the SQL instance.. This took me a while to put together because the (localdb) portion is specific to SQL Express LocalDB.

After we connect to the instance we can further explore the databases (if we are so inclined). Many of the databases are self-explanatory and don’t require further discussion. I did find it interesting as to the structure of the data for the synchronization rules in the synchronization_rule field within the dbo.mms_synchronization_rule table. I’m also curious as to the how the passwords for the management agents are encrypted prior to being base-64 encoded in the encrypted_configuration field in the dbo.mms_managmenent_agent table.

In the next post I’ll take a look at the API the Azure AD Connector uses to synchronize information to Azure Active Directory.


Azure Active Directory Connect – Behind The Scenes – Part 1

Hi all,

I promised to deliver some behind the scenes blogs on Azure Active Directory Connect. I will be delivering on that promise through a series of blog posts that will explore the functionality of the tool that isn’t well documented (if at all documented) by Microsoft. Our first stop in the journey will be exploring how the Azure Active Directory Sync tool handles synchronizations to and from Active Directory Domain Services (AD DS).

The Azure Active Directory Sync component of Azure Active Directory Connect is built from the same framework as Forefront Identity Manager (now called Microsoft Identity Manger (MIM)). This means the connector for AD DS is very similar (possibly a direct port) of the connector used in MIM. So that means all the documentation for this connector is heavily documented with the MIM documentation right? Oh no no no no. What little documentation that does exist for MIM is at the sub-100 level (really Microsoft?). This means we have to be a bit creative in figuring out exactly how the connector is pulling for changes.

I had heard on the grapevine that the AD DS connector uses the uSNChanged method of querying for directory changes as outlined in the following link. To verify this I setup a small lab with a domain controller and a server running Azure Active Directory Connect (AADC going forward). Like any good AD engineer, I cranked up Field Engineering logging on the domain controller per this link. To my surprise, I saw didn’t see any LDAP queries from my AADC server.

My next step was to do some network captures with Wireshark. During the capture I saw the LDAP traffic coming in encrypted via a TLS tunnel. Foiled yet again… or was I? Thankfully Azure Active Directory Sync has an option where encryption of LDAP traffic can be turned off. This is accomplished by opening the Synchronization Service application on the AADC server, navigating to the Connectors tab, right-clicking the Active Directory Domain Services connector, selecting Properties, select Configure Directory Partitions selection, and clicking the Options button. Uncheck both options as seen in the screenshot below. Once encryption is turned off, the LDAP queries can be read.


When we dig through the capture we see the following LDAP query coming from the AADC server:

baseObject: dc=journeyofthegeek,dc=local
Scope: substree
Filter: (&(|(objectClass=computer)(objectClass=contact)(objectClass=container)(objectClass=domainDNS)(objectClass=foreignSecurityPrincipal)(objectClass=group)(objectClass=inetOrgPerson)(objectClass=msDS-Device)(objectClass=organizationalUnit)(objectClass=user))(!(objectClass=groupPolicyContainer))(!(objectClass=msDS-GroupManagedServiceAccount))(!(objectClass=msDS-ManagedServiceAccount))(!(objectClass=msExchConfigurationContainer))(!(objectClass=msImaging-PSPs))(!(objectClass=msPKI-Key-Recovery-Agent))(!(objectClass=rpcContainer))
Attributes: Reference to this link.

    • ControlType: 1.2.840.113556.1.4.417 (LDAP_SERVER_SHOW_DELETED_OID)
    • ControlType: 1.2.840.113556.1.4.529 (LDAP_SERVER_EXTENDED_DN_OID)
    • ControlType: 1.2.840.113556.1.4.2065 (LDAP_SERVER_SHOW_DEACTIVATED_LINK_OID)

<liControlType: 1.2.840.113556.1.4.841 (LDAP_SERVER_DIRSYNC_OID)

The query above is a fairly basic LDAP query. The controls are what we are interested in. Let’s walk through the first three controls quickly.

  1. ControlType: 1.2.840.113556.1.4.417 (LDAP_SERVER_SHOW_DELETED_OID)Quick Explanation: This control tells the directory to return deleted objects that match the query filter.
    More Detail: Link
  2. ControlType: 1.2.840.113556.1.4.529 (LDAP_SERVER_EXTENDED_DN_OID)
    Quick Explanation: This control tells the directory to return the DN preceded by the objectGUID and objectSID in string format.
    More Detail: Link
  • ControlType: 1.2.840.113556.1.4.2065 (LDAP_SERVER_SHOW_DEACTIVATED_LINK_OID)
    Quick Explanation: When used in combination with LDAP_SERVER_SHOW_DELETED_OID, it also returns link (forward/backlink) attributes on deleted object.
    More Detail: Link

The fourth control is the most important piece of the query, so let’s spend some time on it. Active Directory Domain Services provides a few different methods for an application to stay updated on the changes within the directory backend. Three of those methods are change notifications, the DirSync control, and the USNChanged. We are going to focus on the DirSync control, but information on the two other methods can be found here.

The DirSync control allows an application to keep track of changes in the directory by utilizing a piece of data that contains information about the state of the directory as the application last knew it. AD DS puts this of data into a cookie which is updated by the directory each time the application requests a synchronization from the directory. During the initial request (the Full Import run profile in Azure AD Sync) the cookie contains a null value which instructs the directory to return all objects and attributes that match the filter. The directory places a value in the cookie during this initial request. For subsequent requests (the Delta Import run profile in Azure AD Sync) the value of the cookie is used to determine which objects and attributes have changed since the last sync and only that information is returned to the application. The cookie is updated during each subsequent request.

I noticed the connector using the DirSync control I was a bit confused, because much of the documentation out on the web states there are specific permissions and rights required by the identity used by the application in order for that identity to be authorized to leverage the control. After a lot of searching through the web and reading forums, I came across an archived version of an MSDN link that had this interesting piece of information:

LDAP_DIRSYNC_OBJECT_SECURITY (OS): Server 2003 operating system, Windows Server 2008 operating system, Windows Server 2008 R2 operating system, Windows Server 2012 operating system, Windows Server 2012 R2 operating system, and Windows Server 2016 Technical Preview operating system: If this flag is present, the client can only view objects and attributes that are otherwise accessible to the client. If this flag is not present, the server checks if the client has access rights to read the changes in the NC.

This means the identity requesting the use of the DirSync control does not require any permission or right if this flag is set. The caveat being that the application will only receive back the objects and attributes that is authorized to view in the directory.

In the MSDN article noted here, you will notice that the explanation of that flag looks to have been cut off or mistakenly forgotten. Looks like someone made a boo boo. Searching for the flag does yield this article which contains the proper explanation of the flag.

Another thing to note is that DirSync requests to a domain controller are not logged in any event log that I could find. Additionally, they are not logged as traditional LDAP queries are when Field Engineering is enabled. This makes a network capture your only way to identify an application using the DirSync control, unless the application is encrypting the tunnel with TLS. In that scenario you are out of luck. There are rumors that this information will be provided in 2016, but I have yet to test it.

Well there you go, the connector for AD DS uses the DirSync control executed via LDAP to perform its synchronizations against AD DS.

In the next post I will cover the SQL instance that is created during an express installation of Azure AD Connect.