ADFS is almost always configured with a part of it in the public facing DMZ and the server role in the corporate environment. If you’re using pure Microsoft technology for everything, it should just work, and your 411 events should show you the external IP. I’ve seen cases when using external load balancing where it appears that ADFS is working correct, but it probably isn’t working 100% correctly. For example, you always see the hardware load balancer’s IP in the 411. This is wrong and can easily be fixed!

The Issue

ADFS is fairly easy to deploy and configure, that is until you start checking out the Event IDs and in the Security Log and see how it interacts with Azure. You have installed AD Connect and the AD Conect Health Agent for ADFS, right?

Above I mentioned if you’re using 100% Microsoft technology, you would have deployed the Microsoft Windows Application Proxy (WAP)role in the DMZ. Here is where the conundrum comes in. If you have already invested in load balancers and have your standards in place, it would seem overkill and potentially more expensive to deploy two (Highly available) additional Windows Server VMs to host the what seems like a simple proxy role from Microsoft. Why would you do this if you already had the infrastructure in place? This is where the pain comes in if you do not choose the WAP.

Using WAP

The pros

  • Microsoft created their ADFS service
  • Microsoft created their Proxy to work specifically with the ADFS service
  • Oh wait, Microsoft, also created their ADFS Service to work with the Windows Application Role

The cons

  • Added infrastructure (2 VMs?)

Disregarding WAP for Traditional Load Balancers

The pros

  • Using less compute resources
  • Potential VM/agent/operational cost savings
  • Using company owned and deployed technology

The cons

  • None – It does what MS WAP does. It’s a proxy
  • More research required! – You haven’t looked behind the curtain to see what Microsoft is actually doing between WAP and the ADFS Server

The Solution

Well I’ll point you off to some architectural reading for the Microsoft Windows Application Proxy (WAP). If you pop open the link below, you will start scrolling and see how WAP works.

https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-ADFSPIP/%5bMS-ADFSPIP%5d.pdf

I want to focus on section 2.2.1, the HTTP Headers section. This is where I believe most of the problems lie when not using Microsoft WAP.

In short, the client IP in the 411 event feeds the following:

  • Allows you to see the actual client IP of who failed the logon. This should match what flows through your Firewall into the WAP/Load Balancer.
  • If running the AD Connect Health Agent for ADFS, it will send this client IP to show bad login attempts

Implementing the Solution

You need to have your load balancer append additional headers because it does the proxy request.

Because the load balancer is acting as the (WAP) Proxy, it needs to append the following headers –

Header

Description

X-MS-Proxy

MUST contain the value of the server name of the proxy

X-MS-Forwarded-Client-IP

MUST contain the value of the IP address of the client sending the request

X-MS-ADFS-Proxy-Client-IP

MUST be set to the IP address of the client’s TCP/IP connection to the proxy

 

I have not necessarily required these as I’ve found they’ve been usually passed through.

Header

Description

X-MS-Endpoint-Absolute-Path section 2.2.1.3

MUST contain the full URL of the incoming request

X-MS-Target-Role

Not required. This is used when not using a proxy connection

 

Now, I’ve implemented scenarios where the external “Proxy” takes place in the DMZ, and the load balancer is also doing the traditional load balancing of the ADFS Servers in the corporate environment. You only want to add the headers to the traffic when it is coming from the DMZ. For example, if you add the X-MS-Proxy header to internal ADFS request, the ADFS Servers will treat it as an Extranet connection vs and Intranet connection. This is not what you want.

Event ID Checks

Check your 411 Events. They should now contain the external Client IP. If it doesn’t, keep digging and checking your header configuration.

Check your 1203 and 1210 Events. They should also contain hints as to what is going on with the traffic and headers.

 

Hope that helps.

-Allan