Workplace Join failed 0x10dd (a.k.a. how to properly change/set your #ADFS certificates)

This post is really a simple layer-8 issue, but I thought it justified a post as there’s a nuance or two that are worth discussing.  I’m in the process of designing yet another Active Directory Federation Services deployment although this one is more interesting than some of my previous projects as it involves a lot of multi-factor authentication rules and configuration against a lot of trusts for a large user base.  While I’m authoring the design I like to essentially setup the design in my own lab, which is what brings me to this post.  I was enabling the Device Registration Services (DRS) in an existing Active Directory Federation Services (AD FS) 3.0 deployment and, having followed the small and simple set of well documented instructions, realised that my clients could not Workplace Join because the DRS essentially wasn’t there…

The WPJ event log on my Windows 7 desktop that is configured to automatically and silently WPJ showed this event:

image

And this:

image

Clicking that URL returns the browser “This page cannot be displayed” (as opposed to the actual XML when it works correctly) error.

Looks pretty clear.  There’s something really wrong with the DRS endpoint, i.e. it isn’t there (did I forget to enable DRS on each node?), or the DNS entry is wrong, etc.

So I take the URL and try hitting it on each local federation service server node (I have HOSTS entries on each node to hit self and avoid the internal load balancer).  The endpoint isn’t there.  No DNS issue, something else is up.  I dump the HTTP.SYS URLACL list (netsh http show urlacl) and I can see there’s a listener for this URL:

image

Rerunning Enable-ADFSDeviceRegistrationService doesn’t fix the matter.  It does complain about missing UPN suffixes but that’s expected as this is a multi-purpose lab and I have loads of UPN suffixes defined that won’t be used by WPJ clients.

image

I try hitting the https://enterpriseregistration.abstractsynapse.com/EnrollmentServer/contract?api-version=1.0 URL with the FS name instead, e.g.

https://federation.abstractsynapse.com/EnrollmentServer/contract?api-version=1.0 and that works.  I take a look at the certificate and the problem is now obvious.  This certificate doesn’t contain subject alternate name (SAN) properties.  Which is weird because I’ve just procured a new HTTPS certificate with multiple SAN properties to support DRS – as I said at the beginning, I was enabling DRS post-deployment.  My original deployment did not need DRS and therefore only had an SSL certificate with the FS name as the subject.  I have had to enrol a new certificate with multiple DNS SAN attributes for enterpriseregistration.<UPN suffix in use in the enterprise>.

And here’s the crux of the matter and the major layer-8 issue.  When I changed the AD FS certificate I did so using the following command on the primary FS:

Set-AdfsCertificate -CertificateType Service-Communications -Thumbprint “b5 9b d6 af 08 53 08 85 6e b8 aa 52 7b e3 15 65 87 66 e0 f5”

The problem is that command allows you to change the Service Communications certificate, the Token Signing certificate and the Token Encryption certificate.  That command does not change the SSL certificate!

To change the SSL certificate you must use Set-AdfsSslCertificate.  And unlike Set-AdfsCertificate you must do this on each FS node as it is configuring HTTP.SYS (we no longer do this in IIS).

image

Once done, the SAN attributes allow the HTTPS binding to work and the endpoint is live.  WPJ worked immediately then.

Lessons learned

When planning and designing AD FS consider future DRS needs.  Try and get the certificate right up front.  For many customers this is easy – they have a common and consistent UPN namespace, so just get the enterpriseregistration DNS SAN along with the DNS SAN for the FS name, e.g. for sts.contoso.com FS and users with @contoso.com UPN:

  • Subject: sts.contoso.com
  • SAN: DNS=sts.contoso.com
  • SAN: DNS=enterpriseregistration.contoso.com

For more complex deployments look to see what UPNs are in use.  In my experience DRS is closely aligned with cloud deployments and cloud deployments have a dependency on on-premises remediation that rationalises and remedies UPNs among other things.

When deploying the Device Registration Service, remember that the endpoints will only work if you have the correct DNS SAN attributes in your SSL certificate.  Check which certificate is in use using Get-AdfsSslCertificate and Get-AdfsCertificate -Type Service-Communications and also use the browser to validate, i.e. navigate to https://federation-service.domain-name.tld/federationmetadata/2007-06/federationmetadata.xml and look at the certificate in use by your browser – check the subject alternate name and subject fields and the thumbprint.

Lastly, deploying DRS consists of the following commands:

Primary FS (WID deployment):

  1. Initialize-ADDeviceRegistration (Initialise DRS in the AD DS forest – requires Enterprise Admins group membership)
  2. Enable-AdfsDeviceRegistration (Enable DRS on this server)
  3. Set-AdfsGlobalAuthenticationPolicy -DeviceAuthenticationEnabled $true (Enable device authentication in AD FS)

Secondary FS:

  1. Enable-AdfsDeviceRegistration (Enable DRS on this server)

In a SQL deployment you run the first set of commands on one node and the subsequent set of commands on all other nodes.

On your Web Application Proxy servers you might need to reconfigure the SSL endpoint listeners to listen on all of the SANs in your certificate.  You do this using Update-WebApplicationProxyDeviceRegistration.

Summary

When changing your AD FS SSL certificate remember you basically need to do this in two places for 99% of deployments:

  • You set the HTTPS certificate using Set-AdfsSslCertificate on each node in the farm
  • You set the Service Communications certificate using Set-AdfsCertificate on one server – in a WID deployment on the primary, in a SQL deployment on any node

You must also update your Web Application Proxy (WAP) servers, if they’re in play:

  • You set the HTTPS certificate for your WAP servers using the Set-WebApplicationProxySslCertificate cmdlet – again, as with Set-AdfsSslCertificate, this is done on each WAP node as it’s applying the configuration to HTTP.SYS
  • You update the HTTP.SYS endpoints using Update-WebApplicationProxyDeviceRegistration

This is important as the typical deployment pattern expects the service communications certificate to be the same as the federation service (SSL) certificate (it doesn’t have to be, hence the 99% of deployment statement). 

Note that even if you use the GUI you must remember to set the SSL certificate to correctly update the HTTP.SYS bindings.