Configuring APM Client Side NTLM Authentication
After some additional testing, I believe that a Windows Registry check would require something closer to what Michael Koyfman has described. So for clarity, it basically boils down to something like this:
Simplified iRule:
when RULE_INIT {
set static::ntlm_config "/Common/F5NTLM"
}
when ACCESS_SESSION_STARTED {
ACCESS::session data set "session.ntlm.last.retries" 0
}
when HTTP_REQUEST {
switch -glob -- [string tolower [HTTP::uri]] {
"/ntlm/auth" {
if { [HTTP::cookie value MRHSession] ne "" } {
set sid [HTTP::cookie value MRHSession]
}
catch {
set sid [ACCESS::session sid]
}
set referer [HTTP::header value Referer]
set x_session_id [HTTP::header value X-Session-Id]
if { [string length $x_session_id] != 0 } {
set sid $x_session_id
}
set retries [ACCESS::session data get -sid $sid "session.ntlm.last.retries"]
set auth_result [ACCESS::session data get -sid $sid "session.ntlm.last.result"]
if { ($auth_result == 1) || (($retries == 2) && ($auth_result != 1)) } {
ECA::disable
HTTP::redirect $referer
} else {
ECA::enable
ECA::select select_ntlm:$static::ntlm_config
}
unset x_session_id
unset referer
}
default {
ECA::disable
}
}
}
when ECA_REQUEST_ALLOWED {
ACCESS::session data set session.ntlm.last.username "[ECA::username]"
ACCESS::session data set session.ntlm.last.domainname "[ECA::domainname]"
ACCESS::session data set session.ntlm.last.machinename "[ECA::client_machine_name]"
ACCESS::session data set session.ntlm.last.status "[ECA::status]"
ACCESS::session data set session.ntlm.last.result 1
ACCESS::disable
HTTP::header insert X-Session-Id $sid
use virtual [ virtual name ]
}
The set of ACCESS::session set commands in the ECA_REQUEST_ALLOWED event are not expressly required, but useful if you need to access NTLM user information from elsewhere. So basically, once the Windows Registry check determines this is a domain client, control is passed to an external logon page that redirects to itself at the /ntlm/auth URI. The HTTP_REQUEST event in the iRule is triggered and enables/disables ECA based on where you are in the policy evaluation. Once NTLM/ECA succeeds, the ECA_ALLOWED_REQUEST event disables access evaluation and injects the X-Session-ID header.
It's worth noting that if you simply performed an IP subnet check in an iRule, you wouldn't need to do all of this.