ADFS 4.0: Now Allowing You to Authenticate via LDAP

January 11, 2017

While speaking with an IT buddy of mine the other day, a topic of ADFS came up. My buddy had told me he had some struggles getting a SharePoint farm to authenticate with ADFS. His situation was as such:

  • 2 domains – One called EXTERNAL (where vendor accounts are stored) and one called INTERNAL (where internal users are stored)
  • 1 SharePoint 2013 farm – Farm is deployed in the INTERNAL domain
  • 2 ADFS farms – One in the EXTERNAL domain and one in the INTERNAL domain. There is a 2 way trust, however, while forest-wide authentication is allowed, selective authentication is turned on.
  • All internal users will authenticate to SharePoint via WIA (Windows Integrated Auth), and the external vendors will login with SAML Claims Based Auth.

The issues he first spoke of was setting up the ADFS trusts between the 2 domains, as he was not familiar with the setup. The second part was that when he setup SAML auth for SharePoint, he noted that the developers and end-users didn’t like how they had to add users into the system, as it showed multiple entries for one user based on the claims that were provided by ADFS.

He asked me “Hey Corey, do you know if there will ever be a way around this setup, to where I only need 1 ADFS farm?” He asks this because in ADFS 1.0 – 3.0, an Active Directory store is automatically added based on the domain that the Group Managed Service account is created in, or based on the domain service account that you use during the farm creation. Now, the problem here is, you can only have 1 Active Directory attribute store. There are options for LDAP and SQL, however, in the versions mentioned, only Active Directory could be a valid attribute store for ADFS.

So to answer his question, I said “Yes, there is. ADFS 4.0 in Server 2016 now supports LDAP!!!!”

This is for Active Directory Federation Services on Server 2016.

Just to re-iterate - the ADFS has to be Server 2016 - TP4 and above. This will not work on Server 2012 R2 - ADFS 3.0.

I used the following for reference: 

To sum up the main points:

“ADFS supports any LDAP v3-compliant directory.

For ADFS to authenticate users from an LDAP directory, you must connect this LDAP directory to your ADFS farm by creating a local claims provider trust. 

You can support multiple LDAP directories, each with its own configuration, within the same ADFS farm by adding multiple local claims provider trusts. In addition, ADDS forests that are not trusted by the forest that ADFS lives in can also be modelled as local claims provider trusts. You can create local claims provider trusts by using Windows PowerShell.

LDAP directories (local claims provider trusts) can co-exist with AD directories (claims provider trusts) on the same ADFS server, within the same ADFS farm, therefore, a single instance of ADFS is capable of authenticating and authorizing access for users that are stored in both AD and non-AD directories.

Only forms-based authentication is supported for authenticating users from LDAP directories. Certificate-based and Integrated Windows authentication are not supported for authenticating users in LDAP directories. All passive authorization protocols that are supported by ADFS, including SAML, WS-Federation, and OAuth are also supported for identities that are stored in LDAP directories.

The WS-Trust active authorization protocol is also supported for identities that are stored in LDAP directories.”

And:

"In ADFS v1.0 and ADFS v1.1 it was possible to use both AD and AD LDS / ADAM as an identity store. One of the very common scenarios is to use the AD identity store for internal users and use the AD LDS / ADAM identity store for external users (e.g. partners, customers, vendors, etc.). 

All the ADFS versions starting with ADFS v2.0 and higher only supported AD as the identity store and nothing else. That could be one of the reasons why some companies remained using ADFS v1.x. 

If you would like to support a similar scenario, where you would like to have a separate identity store for externals, you would need to either:

  • Configure a separate AD with its own ADFS infrastructure and configure federation between them
  • Use Azure AD to store those identities and configure federation"

With Server 2016 and ADFS 4.0, the last paragraph is no longer true.

ADLDS is an instance of an LDAP and hence can be supported by ADFS 4.0. This means you can finally retire that instance of ADFS 1.x.

Cue massive applause!!!!!!!!!!! :-)

Well Cool Corey, But How does it work?

Below I will demonstrate an example of how I did all of this for a client of Sparkhound’s recently.

This all must be done with PowerShell. The instance names are part of a demo environment I setup for this purpose.

You will start off with the following cmdlet:

$DirectoryCred = Get-Credential

This pops up the credential box. I used my domain admin. account for this part.

Now before I start, let's go over my setup:

  • 2 Domains – 2 way trust, forest-wide auth, selective domain auth (dev.com and dev.local)
  • 1 ADFS Server – resides in dev.com

Same scenario as stated earlier. Now that I’ve covered that, let’s move on to the next set of cmdlets. What we are essentially doing here is setting the new Attribute store and the attribute claims we want to pull from it.:

$vendorDirectory = New-AdfsLdapServerConnection –HostName dc1.dev.local –Port 389 SslMode None –AuthenticationMethod Basic –Credential $DirectoryCred

$GivenName = New-AdfsLdapAttributeToClaimMapping –LdapAttribute givenName –ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname”

$CommonName = New-AdfsLdapAttributeToClaimMapping –LdapAttribute cn –ClaimType “http://schemas.xmlsoap.org/claims/CommonName”

$Surname = New-AdfsLdapAttributeToClaimMapping –LdapAttribute sn –ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname” 

$Email = New-AdfsLdapAttributeToClaimMapping –LdapAttribute email –ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email” 

$UPN = New-AdfsLdapAttributeToClaimMapping –LdapAttribute UPN–ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/UPN” 

Add-AdfsLocalClaimsProviderTrust –Name "AD LDS" –Identifier "testing" –Type Ldap -LdapServerConnection $vendorDirectory –UserObjectClass user –UserContainer " DC=dev,DC=local" –LdapAuthenticationMethod Basic –AnchorClaimLdapAttribute mail –AnchorClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" –LdapAttributeToClaimMapping @($GivenName, $Surname, $CommonName, $Email, $UPN) -AcceptanceTransformRules "@RuleName = `"Issue All Mapped Claims`"`nc:[] => issue(claim = c);" –Enabled $true

This will give a warning:

"WARNING: PS0245: Because no organizational account suffixes were specified, this claims provider trust will not be accessible by requests that use the active profile."

If you want this, you need to run this cmdlet (replacing my suffix with yours):

Set-AdfsClaimsProviderTrust -TargetName "AD LDS" -OrganizationalAccountSuffix @("dev.local")

When I setup the local CP (claims provider) trust, I got an error around invalid credentials. I eventually noticed that I had omitted to define $Surname. Once I fixed that, the error went away. That error is very misleading!

Also note that the new CP will not be displayed in the ADFS wizard.

You can, however, see it with this PowerShell cmdlet: 

Get-AdfsLocalClaimsProviderTrust

Which will return the following:

UserObjectClass            : user

UserContainer              : DC=Dev,DC=Local

AnchorClaimLdapAttribute   : mail

LdapAuthenticationMethod   : Basic

LdapServerConnection       : {dc1.dev.local}

LdapAttributeToClaimMapping : {Microsoft.IdentityServer.Management.Resources.LdapAttributeToClaimMapping, Microsoft.IdentityServer.Management.Resources.LdapAttributeToClaimMapping,

                             Microsoft.IdentityServer.Management.Resources.LdapAttributeToClaimMapping}

LocalClaimsProviderType    : Ldap

AnchorClaimType            : http://schemas.xmlsoap.org/ws/...http://schemas.microsoft.com/w...

Identities                 : {http://schemas.microsoft.com/ws/2009/12/identityserver/TP4-1}

AcceptanceTransformRules   : @RuleName = "Issue All Mapped Claims"

                             c:[]

                              => issue(claim = c);

OrganizationalAccountSuffix : {}

Enabled                    : True

IsLocal                    : True

Identifier                 : testing

Name                       : AD LDS

Notes                      :

ProtocolProfile            : WsFed-SAML

To test this, I simple went to the idpinitiatedsignon page. Yep, it’s just that simple.

When I bring up the sign-on page, I now see this below:

1

Currently, I’m logged in as my dev.com user. If I click other organization (which this is customizable), it will ask me to put my username and password in. Because I’m signed into the dev.com domain, I could just click Active Directory and SSO using my own creds, or if I had this site stored in the Local Intranet Internet Options, it would have just logged me in. But, because that is not the case, I will need to sign in, which is the behavior I would want from someone external of the company. So I’ll click Other organization and sign in with my dev.local credentials. And now:

Capture

BAM! Signed in. So now this means we can just use this to eliminate the need for SAML auth to SharePoint, and can simple use KCD (Kerberos Constrained Delegation) to send users to ADFS first before logging into a SP Web Application. This also provides a lot of other benefits for other applications that you have or plan on using ADFS for.

So now, Goodbye ADFS 1.x!

Enjoy!

For more on what’s new in ADFS 4.0, check out this article from Microsoft below:

https://technet.microsoft.com/en-us/windows-server-docs/identity/ad-fs/overview/whats-new-active-directory-federation-services-windows-server-2016

Information and material in our blog posts are provided "as is" with no warranties either expressed or implied. Each post is an individual expression of our Sparkies. Should you identify any such content that is harmful, malicious, sensitive or unnecessary, please contact marketing@sparkhound.com.

Meet Sparkhound

Review our capabilities and services, meet the leadership team, see our valued partnerships, and read about the hardware we've earned.

Engage with us

Get in touch with any of our offices, or check out our open career positions and consider joining Sparkhound's dynamic team.