SAML SLO request ignored on iRules
Hello all,
the F5 still doesn't pass the relay state on single logout (see https://devcentral.f5.com/questions/saml-logout-relaystate), I've tried to go around using an iRule (store the RelayState in a session and inject the value into the response POST form). IMHO the idea is good, but there's a little problem.
The HTTP_REQUEST event is NOT invoked on SLO (single logout POST to "/saml/idp/profile/post/sls"). I assume other events are skipped too..
Is there another way to handle/enable the events? Using BIG-IP 11.4.1 Build 635.0 Hotfix HF2
Best regards Gabriel
irule to fix SLO bug (not adding RelayState to the response)
when HTTP_REQUEST {
set uri [HTTP::uri]
set method [HTTP::method]
log local0. "aether req: $method $uri"
check if SLO request is invoked
if so, collect the posted content to process
if {$method equals "POST" and $uri equals "/saml/idp/profile/post/sls"} {
if { [HTTP::header Content-Length] ne "" and [HTTP::header value Content-Length] <= 1048576 } {
set content_length [HTTP::header value Content-Length]
} else {
set content_length 1048576
}
if { $content_length > 0 } {
HTTP::collect $content_length
}
}
}
at the SLO request, find the RelayState and store into the session
when HTTP_REQUEST_DATA {
Do stuff with the payload
set uri [HTTP::uri]
set method [HTTP::method]
if {$method equals "POST" and $uri equals "/saml/idp/profile/post/sls"} {
set payload [HTTP::payload]
set relaystate ""
foreach x [split [ string tolower $payload] "&"] {
if { $x starts_with "relaystate=" } {
set relaystate [lindex [split $x "="] 1]
}
}
log local0. $relaystate
session add uie relaystate $relaystate
log local0. "SAML SLO fix: stored relaystate [session lookup uie relaystate]"
}
}
if relaystate is stored (we assume SLO in progress)
we will inject the realystate into the response
when HTTP_RESPONSE {
set relaystate [session lookup uie relaystate]
if {$relaystate ne ""} {
set clen [HTTP::header Content-Length]
log local0. "SAML SLO fix: stored relaystate $relaystate , injecting into the response"
set payload [HTTP::payload]
regsub -all { } $payload" " " newpayload
log local0. "new payload: $newpayload"
session delete uie relaystate
HTTP::payload replace 0 $clen $newpayload
HTTP::release
}
}
You can define a layered VS that apply your irule :
-
Change the IP address of your current VS (for example: 1.1.1.1) and remove your irule
-
Create a new VS (with published IP) and add your irule.
-
just add
to the end of the HTTP_REQUEST event of your irule (where Internal_VS is your VS with IP 1.1.1.1)virtual /Common/Internal_VS
Thus, you will be able to manipulate REQUEST and RESPONSE (HTTP_RESPONSE) without any issues.
-