Forum Discussion
AndOs
Dec 16, 2012Cirrostratus
After a lot of trial and error, I managed to piece together an iRule from various sources here on devcentral.
Turned out to be a bit trickier than I thought, because there may be several tcp connections open from the browser to the web interface, and all those
are authenticated in APM. So simply expiring the APM session cookies and redirecting back to the logon page did not work.
The browser would in that case use another, already establised, connection to request logon page, and (from what I can understand) APM would just send
the request through and the user ended up beeing logged on to the web interface again.
So to get around that I store the session id in a table and check subsequent requests if they are for a logged out session.
Any comments or suggestions greatly appreciated :)
when RULE_INIT {
set ::debug 0
set ::logonpage "https://logon.company.com/"
set ::logoffURI "/auth/loggedout.aspx"
}
when ACCESS_ACL_ALLOWED {
if {$::debug > 1 } { log local1. "uri=[HTTP::uri] | session=[ACCESS::session sid] | client=[IP::client_addr]:[TCP::client_port]" }
Has the user logged off?
if {[HTTP::uri] contains $::logoffURI } {
if {$::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 -subtable "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 {$::debug} { log local1. "MRHSession=$MRHSession" }
}
if {[HTTP::cookie exists "LastMRH_Session"]} {
set LastMRH_Session [HTTP::cookie LastMRH_Session]
if {$::debug} { log local1. "LastMRH_Session =$LastMRH_Session " }
}
}
}
when HTTP_RESPONSE {
set sessionstatus [table lookup -subtable "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 {$::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 {$::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 {$::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 {$::debug} { log local1. "looping cookies..." }
foreach orgCookieName [HTTP::cookie names] {
if {$::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 {$::debug} { log local1. "Custom cookies: $cookieheaders" }
Send a redirect response to the client. With Connection: Close!
if { $cookieheaders != "" } {
HTTP::respond 302 Location "$::logonpage" "Set-Cookie" $cookieheaders "X-OLL-CTX-LOGOUT" "1" "Connection" "Close"
} else {
HTTP::respond 302 Location "$::logonpage" "X-OLL-CTX-LOGOUT" "1" "Connection" "Close"
}
}
}