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 john@contoso.com and another object could have a value in its proxyAddresses attribute of SMTP:john@contoso.com. The same goes for an object that has a mail attribute of john@contoso.com and another object has a value in its proxyAddresses of john@contoso.com.

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 john@contoso.com and another use object with mail attribute of john@contoso.com.

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
userPrincipalName: jess.felton@journeyofthegeek.com
proxyAddresses: SMTP:felton@feltonma.com
Sync Status: Already synced to Azure AD

Object 2
userPrincipalName: matt.felton@journeyofthegeek.com
proxyAddresses:
mail: felton@feltonma.com
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:

Screen-Shot-2016-06-05-at-8.07.18-PM.png

Screen-Shot-2016-06-05-at-8.08.24-PM

The net result of the above matt.felton@journeyofthegeek.com 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.

Screen-Shot-2016-06-04-at-8.47.22-PM.png

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.

Thanks!

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.

Screen-Shot-2016-06-02-at-8.49.54-PM

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.
Controls:

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

Experimenting with Azure B2C – Signup Policies

Hi Everyone,

Before we do a deep dive into Azure Active Directory Connect, I want to spend some time on Microsoft’s Azure Business-To-Consumer (B2C) feature. Behind all the marketing hype, B2C is essentially an external security token service (on steroids) that is integrated with Azure Active Directory. In addition to the standard role of producing security tokens, the service provides self-service provisioning, self-service password reset, and profile editing. All of these features are packaged into an easy solution that can be integrated into native and web apps. If you’d like to learn more, please check out the Microsoft documentation. With the short intro out of the way, let’s start digging in.

So you aren’t a developer but you’d like to understand how these features work and what business problems they could solve for your customers or clients. In comes PowerShell. For those of us who have limited to no developer experience, PowerShell provides a means to experiment with these features. With a few simple lines of code, we can test out the self-provisioning feature of B2C.

In this scenario, we will be running a sign-up policy, emulating a native app, and using LinkedIn as our IdP. Follow the steps below to setup the sample application:

  1. Create a B2C Directory

    Our first step is to create a B2C directory in Microsoft Azure. This is done through the classic management portal within Azure. Go through the standard process of creating a directory instance and ensure you check the box This is a B2C directory.

  2. Register B2C at Linkedin

    Before Microsoft’s B2C feature can obtain information from LinkedIn, it must be registered. Applications can be registered with LinkedIn at https://www.linkedin.com/secure/developer. During the first portion of the registration you’ll be prompted to enter some information about the application name, description, and the like. Enter whatever you’d like, it’s not important.On the next screen, you’ll be given your client ID and client secret. This information should be treated the same way you treat any of your credentials. Don’t accidentally post it to the Internet like so many developers do. You also need to add an authorized redirect URL. This will be in the format of https://login.microsoftonline.com/te/<tenantID>/oauth2/authresp. See the screenshot below for an example.

    LinkedIn.png

  3. Add LinkedIn as an IdP in Azure

    Your next step will be to configure LinkedIn as an IdP within Microsoft Azure. This is done through the new management portal in Azure. After you login, you’ll want to change your directory instance by clicking the user icon in the top right hand corner of the screen and selecting your new B2C directory. From there, search for the B2C blade and hit the settings button (the gear icon).Select the Identity Providers node and click the Add button. Enter the name LinkedIn, select LinkedIn from Identity provider type, and from the Set up this identity provider enter the client ID and client secret obtained from LinkedIn. Hit the save button and move to the next step.

  4. Register your application with Azure B2C

    Now it is time to register our imaginary application with Azure B2C. From within the B2C settings blade, select the Applications node and click the add button. Enter a name for the application, ensure the Native client option is set to Yes and copy the redirect URI. Click the save button.After your application is registered, select it and copy the redirect URI and Application Client ID. You’ll need this information once we setup the script.

  5. Create a custom attribute

    Here we take an optional step to create a customer attribute. We do this because we’ll examine how the attribute is presented in the access token when we cover a SignIn policy at a later date. Developers may use custom attributes to gather additional information to make decisions within their application. For example, during provisioning, the developer may ask the user to select the industry in which they work in. This information could then be used to customize content within the application.To create the attribute select the User attributes node and follow the prompts. I created a custom attribute named Function that users are required to populate during provisioning.

  6. Create a Sign-Up Policy

    Now we will create our first sign-up policy. Select the Sign-Up policies node and hit the add button. Enter a policy name of B2C-1-Signup. Enter the following information for the settings listed below. Leave the rest at the defaults.

    • Identity Providers – LinkedIn, Email Signup
    • Sign-up attributes – Select all attributes

At this point we have registered our instance of B2C with LinkedIn, registered our application with B2C, and configured our signup policy. We’re almost ready to do some PowerShell scripting. Before we can get into the scripting, we need to download the beta ADAL .NET libraries from nuget.

You’ll want to download the nuget command line utility 3x. It’s a simple standalone executable we will use to download the appropriate the ADAL library from Nuget gallery. Once the command line utility is downloaded, open a Windows command prompt and run the command belong where destination is the directory you want to store the libraries.

nuget install Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory -pre -OutputDirectory destination

We’re now ready to see just how simple and powerful the B2C features are. Download the ZIP file below and extract the PowerShell script. You’ll want to open the script up and fill the necessary variables per the instructions above.

B2C Signup Demo

A big thanks to Shriram over at MSFT for the portion of the script that decodes the JWTs returned after the sign-up policy is successfully processes. His full script is located here.

After filling in the appropriate variables per the instructions in the script, you’ll be good to go. Remember to modify the section where the ADAL libraries are loaded with the location you saved the libraries to. When the script is run the sign-up policy will initiate and the user will be prompted to select from either an email signup (creation of a managed Azure Active Directory account) or use their LinkedIn account. See the screenshot below:

SelectIdP.png

After the user opts to select their LinkedIn account, they will be prompted to log into LinkedIn and consent to B2C accessing portions of their profile information as seen in the screenshot below.

authorize.png

After the user authenticates to LinkedIn and consents, they will be prompted to fill in the information you configured as being required in the sign-up policy as seen in the screenshot below. Look closely and you’ll see some information has been pre-populated from information in my LinkedIn profile.

Attributes.png

After the user fills in the required information, an OAuth bearer access token will be returned to our application (in this case our PowerShell instance). The function written by Shriram will parse the token and return the claims in the JWT similar to the screenshot below.

JWT.png

Within the token we see that the IdP that created the token was LinkedIn. To round it out, open up your B2C Directory in the classic management portal and you’ll see a new user object has been provisioned for the user.

What you’ve seen here is a quick and dirty way to demo the B2C functionality. Over the next few days, we’ll explore the other features including sign-in and password reset. We’ll spend more time looking at the access tokens generated with those policies.

A few things to note:

  1. Be careful with what Application Claims you configure in your sign-up policies. If you configure claims that aren’t provided by the IdP, Microsoft throws a really cryptic error. I ended up having to debug the issue in Fiddler. The problem that pops up is the B2C feature will make a call to the B2C directory looking for the user object to pull the additional claims. Well, that user object doesn’t exist, so instead an error is thrown.
  2. The experimental ADAL .NET libraries are not currently documented anywhere that I could find in the MSDN website. Thankfully I came across a link at symbolsource.org which had a nice breakdown of each function and an explanation of the parameters. You can find that link here.Enjoy!