Install ADFS 2.1 on Windows Server 2012 for Office 365 (Part 3)

This is a continuation of a series of posts dedicated to setting up ADFS 2.1 on Windows Server 2012 for Office 365 single sign-on. See Part 2 post for more information on the objectives and the network diagram of the setup we are working on.

In this post, I am going to set up the remaining component of the ADFS infrastructure, namely, the ADFS proxy servers. In addition we will also configure IdP Initiated Sign-On redirect pages and talk about authentication handlers and EAP in ADFS.

Step 8: Deploy ADFS Proxy Servers

The following steps will need to be performed on all ADFS proxy servers in the proxy farm.

Note: do not join ADFS proxy servers to the domain, do not disable UAC, and do not modify MSIE ESC settings on these servers. They need to be treated as semi-trusted, and relaxing security policies on them goes slightly against the idea of having ADFS proxy servers in the first place.

  1. Open Notepad in elevated mode, edit C:\Windows\System32\Drivers\Etc\Hosts file and add the two records as per diagram in the previous post. The two records are sts.flexecom.com (the main secure token service website, pointed to the NLB VIP on the internal network) and mail.flexecom.com (optional, for IdP Initiated Sign On, pointed to the NLB VIP on the internal network but must be different from STS)
  2. Copy sts.flexecom.com.pfx certificate to the server and import it into computer store
  3. If the server is located in the DMZ between the two firewalls, point the default gateway to the firewall that is between DMZ and the Internet (refer to the diagram in the previous post). In this case, also add a persistent static route to the local routing table on the ADFS proxy server, but this step will vary from network to network and may be optional
  4. Confirm that the time is accurate on ADFS proxy servers and that it is synced with Active Directory where internal ADFS servers are members
  5. Create a local admin account service-adfsp

Now some command lines for some of the steps above. Certificate import:

Certutil.exe -importpfx sts.flexecom.com.pfx

Add a persistent static route for the internal network connection:

route add 192.168.1.0 mask 255.255.255.0 10.1.1.2 metric 10 -p

Time sourcing (ADFS depends on time sync; if the skew is off by more than the allowed window, ADFS proxy servers will not negotiate a trusted connection with the internal ADFS farm servers):

w32tm /config /manualpeerlist:192.168.1.11 /syncfromflags:manual
net stop "windows time"
net start "windows time"

Now comes installation of the ADFS proxy components:

Add-WindowsFeature ADFS-Proxy

Let’s create a new web site binding:

New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -IPAddress "10.1.1.10" -SslFlags 0

Now open IIS Management snap-in and do two things: 1 – assign sts.flexecom.com certificate to the 10.1.1.10 binding under Default Web Site, 2 – force SSL on this website.

And finally the ADFS proxy configuration command that brings up ADFS proxy services:

C:\Windows\ADFS\FspConfigurationWizard.exe /hostname sts.flexecom.com /username FLEXECOM\service-adfs /password <service account password>

At this point, if all went well, your proxy server is active. To confirm this, open Event Viewer, go to Applications and Services Log, AD FS, Admin. You should see informational messages only, no errors. Of particular interest is Information event ID 245, which confirms that ADFS proxy was able to negotiate service parameters with internal ADFS farm.

Patch the server.

Step 9: Configure NLB or HLB for the ADFS Proxy Farm

We will skip this step as it was reviewed in detail in Step 7, Part 2 of this post series. Idea is the same, IP addresses and server names will be slightly different.

So, to review… The existing addressing and network requirements of the ADFS services were:

  1. External DNS zone has A record sts.flexecom.com that points to 1.2.3.4 public IP address
  2. 1.2.3.4 NATs port 443 only to 10.1.1.10 DMZ NLB VIP (ADFS Proxy farm)
  3. ADFS Proxy farm has an SSL binding in Default Web Site that uses 10.1.1.10 and sts.flexecom.com certificate
  4. As soon as the SSL tunnel is established between external client and ADFS Proxy, the proxy resolves the name sts.flexecom.com to connect to the internal ADFS Farm. This name resolves to 192.168.1.20 due to hosts file
  5. ADFS proxy routes this request to internal firewall due to persistent static route entry
  6. Request comes into one of the ADFS farm servers on the internal network, which has Default Web Site with its own SSL binding that uses 192.168.1.20 IP address and the same sts.flexecom.com certificate
This is the only way to implement ADFS internal farm with ADFS proxy, both running on Microsoft Windows Server 2012. Instead of Microsoft ADFS Proxy you could in theory use a hardware SSL offloading device, or a non-Microsoft proxy server. This is possible but is outside the scope of our write-up.
Clients that connect from the internal network do not use steps 1 through 5 and instead use internal DNS zone to lookup sts.flexecom.com, get internal ADFS farm NLB address, and connect to the internal NLB VIP directly.

Step 10: Configure Additional Website for Office 365 Landing Page

This step is totally optional, but most people will do it to make sure that users get one easy URL to remember, when it comes to accessing Office 365 services. In my case, this URL will be: mail.flexecom.com. My users will be accessing Office 365 Web Apps by simply typing in “mail.flexecom.com” in the browser.

Most people will find it useful to enable both port 80 and 443 for this landing page, just to make sure that users who type it into a mobile client won’t have to be bothered with typing in https://. However, you may also want to enable https on port 443, in which case you need a separate IP address from what we used to configure ADFS NLB – this is why we added the second VIP to both NLB clusters.

Why Use Additional Public IP Address

To enable this functionality and stay close to a supported Microsoft configuration, you will need to create a new IIS website, with its own SSL listener. Why? Because you cannot bind more than one SSL binding to the same IP:Port443 combination, and because all of our ADFS servers already have one SSL binding setup for token traffic. This is different from IP:Port80, where you can have many websites with the same binding as long as you use different host headers. IIS cannot see the host header in the incoming SSL-encrypted packet, until after it decrypts it. For this reason a valid and unique binding must exist on every SSL-enabled IIS website on the same server.

(Note that there is an exception to this statement above, if you are using wildcard or SAN – subject alternate name – certificates. If that is the case, you can publish multiple websites on the same IP address using the same certificate, conserving IP address space. But, as it stands now, we are told to use simple, single-name certificates for ADFS services, which means we have use two certificates and two IP addresses to enable this configuration. This may change in the future but for now we need two public IP addresses for this setup).

Configure the Landing Website

So to add to the numbered list mentioned in Step 9, we are going to:

  1. Add a new external DNS zone A record, mail.flexecom.com = 1.2.3.5
  2. Setup a new firewall rule to allow 1.2.3.5:80 and 1.2.3.5:443 and NAT them into DMZ NLB VIP 10.1.1.20
  3. Create a new website on all ADFS proxy servers and bind it to 10.1.1.20, ports 80 and 443, using mail.flexecom.com certificate
  4. Add mail.flexecom.com A record to hosts file on all ADFS proxy servers and point it to 192.168.1.30 internal ADFS farm NLB VIP
  5. On the internal network, create a new A record in internal DNS zone to point mail.flexecom.com to 192.168.1.30
  6. Finally, create a new website on all internal ADFS farm servers and bind it to 192.168.1.30, ports 80 and 443, using mail.flexecom.com certificate

It’s not all that complicated but the number of steps involved makes it look like something one would want to avoid.

Since we are creating a new website on all ADFS servers in the topology, a little automation would not hurt.

mkdir c:\inetpub\mail.flexecom.com
New-Website -Name mail.flexecom.com -Port 80 -HostHeader mail.flexecom.com -PhysicalPath "$env:systemdrive\inetpub\mail.flexecom.com"
New-WebBinding -Name mail.flexecom.com -Protocol https -Port 443 -IPAddress "10.1.1.20" -SslFlags 0

On the internal ADFS farm servers you will need to change IP address in the last command to 192.168.1.30. In all cases, once this binding is created, you need to manually assign the X509 certificate in the mail.flexecom.com website properties, bindings. Also, do NOT force SSL on this website because we actually want users to connect on port 80.

Step 11: Configure IdP Initiated Sign On

In Step 10 we configured a website for a landing page, but there is no landing webpage per se. What we are going to do instead is use ADFS SmartLinks with HTTP Redirect to bounce the user straight to our internal ADFS server for authentication and token issuing. Once the user has the token, they will forward it directly to Office 365 Outlook Web App. This is a combination of IdP-Initiated Sign-On with SmartLinks.

In a standard setup, ADFS with Office 365 works like this:

  1. The user goes to portal.microsoftonline.com and types in user@flexecom.com login
  2. Portal contacts Microsoft federation server to figure out how to route this request
  3. Microsoft federation server has information on the trust with Flexecom and redirects authentication request to sts.flexecom.com ADFS service endpoint
  4. The user lands on our ADFS proxy (or internal farm, depending on the user location)
  5. The user authenticates to internal AD via ADFS and gets the token
  6. The user is redirected back to Microsoft federation server
  7. The user is redirected to the portal.microsoftonline.com site
  8. Finally, they can now click on Outlook icon to get into their mailbox.

Too many redirects.

IdP Initiated Sign On to the rescue:

  1. The user goes to mail.flexecom.com and immediately gets redirected to sts.flexecom.com using a SmartLink, that among other things also embeds the target service URL = outlook.com
  2. The user authenticates to internal AD via ADFS and gets the token
  3. The user is redirected to Microsoft federation server
  4. The user is redirected straight to outlook.com Office 365 Web App

Done! And if the user is located inside the network and has sts.flexecom.com in their Local Intranet MSIE security zone, this entire process works completely transparently and without as much as a single click.

To set this up, we will run the following command on the mail.flexecom.com site that we created earlier. This needs to be done on all ADFS servers, internal and proxy:

Set-WebConfiguration system.webServer/httpRedirect "IIS:\sites\mail.flexecom.com" -Value @{enabled="true";destination="https://sts.flexecom.com/adfs/ls/?wa=wsignin1.0&wtrealm=urn:federation:MicrosoftOnline&wctx=MEST%3D0%26LoginOptions%3D2%26wa%3Dwsignin1.0%26rpsnv%3D2%26ct%3D1292977249%26rver%3D6.1.6206.0%26wp%3DMCMBI%26wreply%3Dhttps:%252F%252Foutlook.com%2fowa%2fflexecom.com%2f?exsvurl=1&ll-cc=en-US%26lc%3D1033%26id%3D271345";exactDestination="true";httpResponseStatus="Found"}

This command adds a 302 “Found” redirect and does not actually require the landing page to exist – this is an empty site with a redirect. Since we redirect everyone to an HTTPS site where the token is issued, there is no problem with allowing the users to hit this website over unencrypted port 80.

Step 12: Configure ADFS Authentication Handlers

ADFS authentication handlers dictate which authentication method is used when the users send authentication requests to ADFS. This file is located in

C:\inetpub\adfs\ls\web.config

on all ADFS servers, proxy or not. By default, ADFS farm servers on the internal network will be configured to use Windows integrated authentication:

  <microsoft.identityServer.web>
    <localAuthenticationTypes>
      <add name="Integrated" page="auth/integrated/" />
      <add name="Forms" page="FormsSignIn.aspx" />
      <add name="TlsClient" page="auth/sslclient/" />
      <add name="Basic" page="auth/basic/" />
    </localAuthenticationTypes>

By default, ADFS proxy servers will be configured to use forms-based authentication:

  <microsoft.identityServer.web>
    <localAuthenticationTypes>
      <add name="Forms" page="FormsSignIn.aspx" />
      <add name="Integrated" page="auth/integrated/" />
      <add name="TlsClient" page="auth/sslclient/" />
      <add name="Basic" page="auth/basic/" />
    </localAuthenticationTypes>

By changing the order in which authentication types are defined, you can manipulate authentication behavior of the ADFS services. Usually you would want to leave these defaults, but in some cases it may be desirable to change the internal ADFS servers to use forms-based authentication, for example to ensure that all users get consistent authentication experience regardless of what network they are on.

One downside to enabling forms-based authentication on the internal ADFS servers is that users on domain-joined computers will lose “single sign on” experience and will be prompted for credentials via the web form. With integrated authentication, all they would need to do to access Office 365 service is to open the browser and navigate to mail.flexecom.com.

Step 13: Configure ADFS Extended Protection

By default, ADFS services use something called Extended Protection Token Check, which allows ADFS to verify if the token passing was tampered with in any way and ensure that no man in the middle attack is taking place. This is a good security feature to have, except that you may have to disable it in two scenarios.

The first scenario involves Chrome, Safari, and Firefox users on the internal network. If internal ADFS farm does not use forms-based authentication and instead relies on the integrated authentication, non-MSIE clients will not be able to authenticate. They would be getting continuous password prompts that just won’t go away.

The second scenario involves using application-layer firewalls such as ISA, TMG, UAG, or a third-party layer 7 product such as an SSL offload device. If TMG server is configured to bridge SSL traffic (i.e. decrypt SSL tunnel, inspect HTTP content, re-encrypt it into SSL and send on to ADFS), Extended Protection breaks down. One way to resolve this problem is to not bridge SSL traffic and instead send it through directly, at layer 3. But this defeats the purpose of using application layer security devices.

To fix this issue on Windows Server 2012 ADFS 2.1 servers, the following steps are required on all internal ADFS farm servers:

Set-ADFSConfiguration -ExtendedProtectionTokenCheck "None"

Then, access IIS Management, Default Web Site, /adfs/ls directory, Authentication, Windows Authentication. Click on Advanced Settings and set Extended Protection dropdown to “Off”.

Now

iisreset.exe
net stop "ad fs windows service"
net start "ad fs windows service"

Done.

In the next post, we will deal with Office 365 Dirsync on Windows Server 2012.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>