Once the Azure implementation of Active Directory Federation Services (ADFS) was in place I ran through the test process. Single Sign on works as expected from inside the network. Going to microsoftonline.com passes my client to the internal ADFS server where I enter my user name and get redirected to the Office 365 landing page. Doing the same from outside the corporate network works similarly only directing me to the external servers where I had to enter my domain UPN (username) and password. All well, but then…
The problem was connecting to an Office 365 site from a domain joined computer connected outside the corporate network via Direct Access (DA). In this scenario I get the prompt for username and password. This is not ideal, the end users expectation is to have the same experience through DA as in the office.
So what’s going on? There are a couple things in my environment leading up to this issue. First, our internal AD domain and external domain are not the same. We use internal.net for the AD domain and external.com for email, public web site and UPN suffix. Second, we have split DNS for external.com; internal DNS use our AD DNS servers while the external DNS is hosted by a third party. Lastly, we have one hostname (and cert) for the ADFS servers: addfs.external.com. External points to the public IP for the load balancer of our ADFS Web Application Proxies (WAP) and internal points to the internal IP of the internal ADFS Load balancer.
None of the above is out of the ordinary and majority of companies probably has a similar setup. A quick ping to adfs.external.com shows that it resolves to the external IP while on DA. This indicates that the client is getting passed to the WAP load balancer and those servers only allow forms based authentication. So all we need to do is configure DA to resolve adfs.external.com with the internal DNS servers and get the internal IP. This is set in the DirecAccess tunnel with NRPT settings.
The configuration change was made so adfs.external.com resolves to the internal IP address. Once changed, the name resolved to the correct IP. Now there was a new issue; the client is redirected to the internal ADFS server for authentication but the session times out. A couple tests ruled out routing issues and other problems. At this point I suspect the issue still lies in DA.
I have to give credit to Jordan Krause with IVO Networks with all things DA in this post. His help made troubleshooting and understanding this issue possible.
Here is a summery of the problem. DA uses Teredo, IP-HTTPS and/or 6To4 for tunneling. One of the requirements of Teredo is the destination must respond to ping. However, Azure load balancers will not respond to ping. Direct Access will not pass the traffic over the tunnel to the internal load balancers because it will not respond to ping. I was able to verify that was the issue by disabling Teredo on the client with the command “Netsh int Teredo set state disable.” This forced traffic over IP-HTTPS and subsequently SSO functioned the same as if on the corporate network.
So, what’s the solution? That’s not a rhetorical question. If you have a solution, please let me know. Unless Azure begins allowing pings to their load balancers or the RFC for Teredo changes there is no solution. The only workarounds I can come up with is disable Teredo, but that would cause a performance issue on the client. Another option is to point the adfs.external.com on the internal DNS servers to one of the ADFS servers instead of the load balancer, but that introduces a single point of failure. Maybe use a non-Azure load balancer that will respond to ping?