Forum Discussion
Gabriel_V_13146
Aug 14, 2014Cirrus
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 ...
- Aug 26, 2014
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.
-
Gabriel_V_13146
Cirrus
posting a complete solution
rule saml-inject rule
irule to store the relay state at the logout (or predefined link)
and inject the relay state to the reply
this irule is to be applied to a front layer VS
thus intercepting all HTTP events
when RULE_INIT {
set static::virtual_SAML_server /Common/auth-test-vs
}
when HTTP_REQUEST {
log local0. "[HTTP::host] [HTTP::method] [HTTP::uri]"
set uri [HTTP::uri]
set method [HTTP::method]
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
log local0. "request content collected: $content_length"
} else {
log local0. "cannot collect the content, length: $content_length"
}
}
else {
unset uri
unset method
}
virtual $static::virtual_SAML_server
}
at the SLO request, find the RelayState and store into the session
triggered by HTTP::collect
when HTTP_REQUEST_DATA {
if { [info exists "uri"] and [info exists "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. "found relaystate: $relaystate"
unset payload
HTTP::release
}
}
}
when HTTP_RESPONSE {
log local0. "response"
if { [info exists "uri"] and [info exists "method"] } {
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
log local0. "response content collected: $content_length"
} else {
log local0. "cannot collect the content, length: $content_length"
}
}
}
}
when HTTP_RESPONSE_DATA {
log local0. "response data"
if { [info exists "uri"] and [info exists "method"] } {
if {$method equals "POST" and $uri equals "/saml/idp/profile/post/sls"} {
set payload [HTTP::payload]
set index [string first " 0 } {
HTTP::payload replace $index 0 ""
}
unset payload
unset index
unset content_length
unset relaystate
}
}
}
when HTTP_RESPONSE_RELEASE {
log local0. "response release"
HTTP::release
}
Gabriel_V_13146
Aug 29, 2014Cirrus
This workaround works only with a single SP. With multiple SPs it will be more complex.
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects