ADFS, WAP and updating their public certificates

Renewing public certificates within an environment is always a bit of a pain – especially when you use the same certificate on a range of different systems and have to update each manually! When you’ve got a number of web-based systems that you publish externally, using a reverse proxy such as a Microsoft Web Application Proxy (WAP) can make the task a little less tedious.

With WAP, you can use a single wildcard certificate to publish any number of web-based services to the public internet. When you need to update the public certificate, you only need to update it in the one place – you don’t need to update each individual web service. In addition, WAP can also act as an Active Directory Federation Services Proxy (ADFS Proxy) – this allows you to present your ADFS infrastructure to the public internet without directly exposing your ADFS server(s).

In general, ADFS and WAP should go hand-in-hand. Internal clients hit the ADFS server directly (via the ADFS namespace), while external clients communicate via the WAP. By doing this, you can also set up different rules in ADFS to define what should happen for external authentication requests, compared to internal authentication requests (e.g: 2-factor auth for external, windows auth for internal).

Now, both ADFS and WAP need to have a public-signed certificate. What happens when those certificates expire? Obviously you need to renew them and update the configuration – which is what prompted me to write this article. Usually this is a pretty simple process – you import the new certificate into the local computer certificate store on each of your ADFS/WAP servers, then update the configuration.

Initially I noticed I was getting the following in the event logs of the WAP server:

Unable to retrieve proxy configuration data from the Federation Service.

Additional Data
Trust Certificate Thumbprint:
<thumbprint>

Status Code:
Exception details:
System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

I had a look at the certificate on the ADFS server and sure enough, the certificate thumbprint matched the expired certificate on the ADFS server. Since I was using that certificate on the WAP server as well, I needed to update it in both systems. I started by importing the new public wildcard certificate into both the ADFS and WAP servers.

The next step is to update the configuration. For ADFS, you can pull up the ADFS console and go to the Service\Certificate node. From there, you select the ‘Service Communications’ certificate, hit the ‘Set Service Communications Certificate’ link, then follow the wizard. Then in the ADFS event log I started getting:

During processing of the Federation Service configuration, the element 'serviceIdentityToken' was found to have invalid data. The private key for the certificate that was configured could not be accessed.

Whoops, I forgot to give access to the service account for the private key! In the Certificate Management console, locate the public cert, right-click, select ‘All Tasks’ – ‘Manage Private Keys’ and make sure the service account has full access. I restarted the ADFS service (adfssrv) and the ADFS server looked to start up successfully. Or so I thought.

Assuming ADFS was all good, I then proceeded to update the main proxy certificate in WAP. To do this you really only have the option to use a powershell command:

Set-WebApplicationProxySslCertificate -Thumbprint <thumbprint>

…and of course I was still getting trust errors. In the end I removed and re-added the WAP role to the server (it was a development environment – and since the rules and configuration are stored with ADFS, it’s wasn’t a huge issue). When trying to re-create the trust to the ADFS server via the wizard, I was getting a trust error – along with the following in the event log:

The federation server proxy could not establish a trust with the Federation Service.

Additional Data 
Exception details: 
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

User Action 
Ensure that the credentials being used to establish a trust between the federation server proxy and the Federation Service are valid and that the Federation Service can be reached.

Odd. I could resolve and ping the ADFS server (both directly and via the ADFS namespace) – and the credentials used were an administrator on the remote server. The new certificate was showing correctly in the ADFS console, and the event logs on the ADFS server indicated it was all fine. So I started going through all the config via Powershell instead. After a bit of investigation, I ran the Get-AdfsSslCertificate  command. Despite the ADFS console showing the correct certificate, powershell was still showing the old one!

I ran: Get-ChildItem -path cert:\LocalMachine\My  to get the thumbprint of the new certificate, then Set-AdfsSslCertification –thumbprint <newthumbprint>  to set it. I restarted the service with Restart-Service adfssrv and double-checked the certificate. Ok, NOW we were looking good.

As it turns out, the GUI wizard will update the configuration in the ADFS database, but not the binding on HTTP.sys.

I re-ran the WAP wizard and everything started working correctly.

One other thing to take note of – the above commands are all about updating certificates specifically for ADFS and the ADFS Proxy (WAP) – if you have additional published rules in WAP, you’ll need to update the certificate thumbprint against those as well!