Why stop at 3 when you can go to 4? Over the past few posts on this ever-expanding topic, we’ve discussed using ADFS to provide single sign-on access to Office 365. But what about single sign-out?

A customer turned me onto Tristan Watkins’ blog post that discusses the challenges of single sign-out for browser-based, (WS-Federation) applications when fronting ADFS with a reverse-proxy. It’s a great blog post and covers the topic quite well so I won’t bother re-hashing it here. However, I would definitely recommend reading his post if you want a deeper dive. Here’s the sign-out process:

1. User selects ‘Sign Out’ or ‘Sign in as Different User’, (if using SharePoint Online);

2. The user is signed out of the application;

3. The user is redirected to the ADFS sign out page; and

4. The user is redirected back to the Microsoft Federation Gateway and the user’s tokens are invalidated.

In a nutshell, claims-unaware proxies, (Microsoft ISA and TMG servers for example) are unable to determine when this process has occurred and subsequently the proxy session remains active. This in turn will allow access to ADFS, (and subsequently Office 365) without be prompted for new credentials, (not good!). Here’s where I come clean with you dear readers. While the F5 Big-IP with APM is a recognized replacement for the AD FS 2.0 Federation Server Proxy this particular topic was not even on my radar.

But now that it is……

 

Single Sign-Out with Access Policy Manager

You’ll may have noticed that although the Big-IP with APM is a claims-unaware proxy I did not include it in the list above. Why you ask? Well, although the Big-IP is currently “claims-unaware”, it certainly is “aware” of traffic that passes through. With the ability to analyze traffic as it flows from both the client and the server side, the Big-IP can look for triggers and act upon them. In the case of the ADFS sign-out process, we’ll use the MSISSignOut cookie as our trigger to terminate the proxy session accordingly.

During the WS-Federation sign out process, (used by browser-based applications) the MSISSignOut cookie is cleared out by the ADFS server, (refer to the HttpWatch example below). Once this has been completed, we need to terminate the proxy session. Fortunately, there’s an iRule for that.

 

The iRule below analyzes the HTTP response back from the ADFS server and keys off of the MSISSignOut cookie. If the cookie’s value has been cleared, the APM session will be terminated. To allow for a clean sign-out process with the Microsoft Federation Gateway, the APM session termination is delayed long enough for the ADFS server to respond. Now, APM’s termination can act in concert with the ADFS sign-out process.

 

   1: when HTTP_RESPONSE {
   2:     # Review server-side responses for reset of WS-Federation sign-out cookie - MSISSignOut.  
   3:     # If found assign ADFS sign-out session variable and close HTTP connection
   4:     if {[HTTP::header "Set-Cookie"] contains "MSISSignOut=;"} {
   5:         ACCESS::session data set session.user.adfssignout 1
   6:         HTTP::close
   7:     }
   8: }
   9:  
  10: when CLIENT_CLOSED {
  11:     # Remove APM session if ADFS sign-out variable exists
  12:     if {[ACCESS::session data get session.user.adfssignout] eq 1} {
  13:         after 5000
  14:         ACCESS::session remove
  15:     }
  16: }

 

What? Another iRule? Actually, the above snippet can be combined with the iRule we implemented in Part 3 creating a single iRule addressing all the ADFS/Office 365 scenarios.


 

 

 

   1: when HTTP_REQUEST {
   2:     # For external Lync client access all external requests to the
   3:     # /trust/mex URL must be routed to /trust/proxymex. Analyze and modify the URI
   4:     # where appropriate
   5:     HTTP::uri [string map {/trust/mex /trust/proxymex} [HTTP::uri]]
   6:  
   7:     # Analyze the HTTP request and disable access policy enforcement WS-Trust calls
   8:     if {[HTTP::uri] contains "/adfs/services/trust"} {
   9:         ACCESS::disable
  10:     }
  11:  
  12:     # OPTIONAL ---- To allow publishing of the federation service metadata 
  13:     if {[HTTP::uri] ends_with "FederationMetadata/2007-06/FederationMetadata.xml"} {
  14:         ACCESS::disable 
  15:     }
  16: }
  17:  
  18: when HTTP_RESPONSE {
  19:     # Review serverside responses for reset of WS-Federation sign-out cookie - MSISSignOut.  
  20:     # If found assign ADFS sign-out session variable and close HTTP connection
  21:     if {[HTTP::header "Set-Cookie"] contains "MSISSignOut=;"} {
  22:         ACCESS::session data set session.user.adfssignout 1
  23:         HTTP::close
  24:     }
  25: }
  26:  
  27: when CLIENT_CLOSED {
  28:     # Remove APM session if ADFS sign-out variable exists
  29:     if {[ACCESS::session data get session.user.adfssignout] eq 1} {
  30:         after 5000
  31:         ACCESS::session remove
  32:     }
  33: }

 

Gotta love them iRules! That’s all for now.

Additional Links:

Big-IP and ADFS Part 1 – “Load balancing the ADFS Farm”

Big-IP and ADFS Part 2 – “APM–An Alternative to the ADFS Proxy”

Big-IP and ADFS Part 3 – “ADFS, APM, and the Office 365 Thick Clients”

BIG-IP Access Policy Manager (APM) Wiki Home - DevCentral Wiki

AD FS 2.0 - Interoperability with Non-Microsoft Products

MS TechNet - AD FS: How to Invoke a WS-Federation Sign-Out

Tristan Watkins - Office 365 Single Sign Out with ISA or TMG as the ADFS Proxy