APM as ADFS proxy in front of ADFS server 3.0 for O365

Problem this snippet solves:

When deploying APM as ADFS proxy in front of ADFS server, there are some issues :

  • user agent different than Internet Explorer are redirected to ADFS form based authentication after APM auth
  • Logout URI is not managed by APM. users disconnected from Office 365 are not disconnected from APM
  • users who are still authenticated on O365 but with expired session on APM are prompted to authenticate on APM when disconnecting from O365
  • When authentication fails, APM display logout page with redirect to /. when user authenticate next time, ADFS server respond with 404 error code.
  • When User try to connect to access URI /, ADFS server respond with 404 error code.

This irule change the APM behavior to optimize user experience.

to solve HTTP error 404, user trying to access / or session denied are redirected to https://portal.office.com

Note : Next step is to extract SAML relay state from request and redirect dynamically 404 error to relay state instead of fixed URL.

How to use this snippet:

Enable this irule on the virtual server.

Code :

when ACCESS_ACL_ALLOWED {
    # Change user-Agent to Internet Explorer 11 User-Agent
    HTTP::header replace "User-Agent" "Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko msie7"
    # If authenticated request matches ADFS SLO URI, close APM session and redirect to URI stored in query parameter "wreply"
    if { ([string tolower [HTTP::path]] equals "/adfs/ls/") && ([string tolower [URI::query [HTTP::uri] wa]] equals "wsignout1.0") } {
        set redirect_uri [URI::decode [URI::query [HTTP::uri] wreply]]
        ACCESS::session remove
        ACCESS::respond 302 noserver Location $redirect_uri
        return
    }
}

when ACCESS_SESSION_STARTED {
    # If new session matches ADFS SLO URI, close APM session and redirect to URI stored in query parameter "wreply"
    set landinguri [ACCESS::session data get session.server.landinguri]
    if { ([string tolower $landinguri] starts_with "/adfs/ls/") && ([string tolower [URI::query $landinguri wa]] equals "wsignout1.0") } {
        set redirect_uri [URI::decode [URI::query $landinguri wreply]]
        ACCESS::respond 302 noserver Location $redirect_uri
        ACCESS::session remove
        return
    } elseif {!([string tolower $landinguri] starts_with "/adfs/")} {
        ACCESS::respond 302 noserver Location "https://portal.office.com"
        ACCESS::session remove
    }
}

when ACCESS_POLICY_COMPLETED {
    if { ([ACCESS::policy result] equals "deny") } {
        ACCESS::respond 302 noserver Location "https://portal.office.com"
        ACCESS::session remove
    } 
}

Tested this on version:

12.0
Published Sep 19, 2016
Version 1.0
No CommentsBe the first to comment