Forum Discussion
hooleylist
Dec 16, 2012Cirrostratus
Nice work in figuring this out.
Make sure to use static variables in RULE_INIT to preserve CMP:
https://devcentral.f5.com/wiki/iRules.CMPCompatibility.ashx
Also, generally you should only use a subtable if you need to count the entries. You can use a prefix on the key names instead to prevent key name collisions.
when RULE_INIT {
set static::access_debug 0
set static::logonpage "https://logon.company.com/"
set static::logoffURI "/auth/loggedout.aspx"
}
when ACCESS_ACL_ALLOWED {
if {$static::access_debug > 1 } { log local1. "uri=[HTTP::uri] | session=[ACCESS::session sid] | client=[IP::client_addr]:[TCP::client_port]" }
Has the user logged off?
if {[string tolower [HTTP::path]] eq $static::logoffURI } {
if {$static::access_debug} { log local1. "Detected logoff!" }
need to track the sessionID because after the redirect has been sent, the browser may use an
already established (access granted) tcp connection that will be allowed through ACCESS_ACL_ALLOED.
table add "ctxloggedoutsessions_[ACCESS::session sid]" 1 60 90
store the APM session cookies from the request.
if {[HTTP::cookie exists "MRHSession"]} {
set MRHSession [HTTP::cookie MRHSession]
if {$static::access_debug} { log local1. "MRHSession=$MRHSession" }
}
if {[HTTP::cookie exists "LastMRH_Session"]} {
set LastMRH_Session [HTTP::cookie LastMRH_Session]
if {$static::access_debug} { log local1. "LastMRH_Session =$LastMRH_Session " }
}
}
}
when HTTP_RESPONSE {
set sessionstatus [table lookup "ctxloggedoutsessions_[ACCESS::session sid]]"
check if this reponse is for a session that has been marked as logged off.
if { $sessionstatus == 1 } {
yes, user has logged off.
if {$static::access_debug} { log local1. "Found session [ACCESS::session sid] in table" }
set cookieheaders ""
prepare the APM session cookies to be expired by setting the date to UNIX TS 0
if { [info exists MRHSession] } {
set cookieheaders "MRHSession=$MRHSession;expires=Thu, 01-Jan-1970 00:00:00 GMT;path=/;"
if {$static::access_debug} { log local1. "setting cookie, MRHSession" }
unset MRHSession
}
if { [info exists LastMRH_Session] } {
set cookieheaders "$cookieheaders\r\nSet-Cookie: LastMRH_Session=$LastMRH_Session;expires=Thu, 01-Jan-1970 00:00:00 GMT;path=/;"
if {$static::access_debug} { log local1. "setting cookie, LastMRH_Session" }
unset LastMRH_Session
}
Loop through all other cookies which are set in the repsonse, and expire those as well.
This does not seem to be needed.
if {$static::access_debug} { log local1. "looping cookies..." }
foreach orgCookieName [HTTP::cookie names] {
if {$static::access_debug} { log local1. "found cookie: $orgCookieName=[HTTP::cookie value $orgCookieName]" }
set cookieheaders "$cookieheaders\r\nSet-Cookie: $orgCookieName=[HTTP::cookie value $orgCookieName];expires=Thu, 01-Jan-1970 00:00:00 GMT;[HTTP::cookie path $orgCookieName];"
}
if {$static::access_debug} { log local1. "Custom cookies: $cookieheaders" }
Send a redirect response to the client. With Connection: Close!
if { $cookieheaders != "" } {
HTTP::respond 302 Location "$static::logonpage" "Set-Cookie" $cookieheaders "X-OLL-CTX-LOGOUT" "1" "Connection" "Close"
} else {
HTTP::respond 302 Location "$static::logonpage" "X-OLL-CTX-LOGOUT" "1" "Connection" "Close"
}
}
}
Aaron