Forum Discussion
Headers not being set at http_request
I am working on a clientless APM process with F5, where the clients requesting a webservice will use http basic authentication to present their credentials. Once the APM retrieves the username/password combo, it authenticates them in the AD. If successful, I grab out a whole bunch of values using an AD query, and then they are passed onto the application. This is how the flow looks like:
Now, as soon as the APM policy has completed, I am parsing out the CN values of all groups they are in, and storing them as some custom session variable. When a http request is made, I look to ensure that the session is established, and insert the constructed headers, as needed by my application. My IRule looks as follows:
when HTTP_REQUEST {
insert clientless mode
set apmsessionid [HTTP::cookie value MRHSession]
if { [HTTP::cookie exists "MRHSession"] } { set apmstatus [ACCESS::session exists -state_allow $apmsessionid]} else {set apmstatus 0}
if {!($apmstatus)} {
Insert Clientless-mode header to start APM in clientless mode
if { [catch {HTTP::header insert "clientless-mode" 1} ] } {log local0. "[IP::client_addr]:[TCP::client_port] : TCL error on HTTP header insert clientless-mode : URL : [HTTP::host][HTTP::path] - Headers : [HTTP::request]"}
}
empty the current headers
HTTP::header remove username
HTTP::header remove domain
HTTP::header remove roles
set the headers needed for the application
HTTP::header insert username [ACCESS::session data get session.custom.login]
HTTP::header insert domain [ACCESS::session data get session.custom.domain]
HTTP::header insert roles [ACCESS::session data get session.custom.roles]
log " sending [HTTP::header username]"
log " sending [HTTP::header domain]"
log " sending [HTTP::header roles]"
}
when ACCESS_POLICY_COMPLETED {
Authentication request for non bowser user-agent session denied
if { ([ACCESS::policy result] equals "deny") } {
ACCESS::respond 401 noserver WWW-Authenticate "Basic realm=\"My Web Services Authentication\"" Connection close
ACCESS::session remove
return
} else {
set allRoles ""
grab the session data containing the groups associated with the member
set s [ACCESS::session data get "session.ad.last.attr.memberOf"]
set matched [split [string map [list {| CN=} \0] $s] \0]
foreach match $matched {
if { $match != "" } {
puts [string range $match 0 [expr [string first , $match] - 1]]
set queryarray [split $match ","]
set firstvalue [lindex $queryarray 0]
set cleaneddata [string toupper [join $firstvalue _]]
if { [string length allRoles] == 0 } {
append allRoles "ROLE_$cleaneddata"
} else {
append allRoles ",ROLE_$cleaneddata"
}
}
}
puts $allRoles
grab the session data containing the username associated with the member
ACCESS::session data set session.custom.login [ACCESS::session data get "session.logon.last.logonname"]
grab the session data containing the domaiin associated with the member
ACCESS::session data set session.custom.domain [ACCESS::session data get "session.ad.last.actualdomain"]
grab the session data containing the roles associated with the member
ACCESS::session data set session.custom.roles $allRoles
}
}
The issue I am having is that the first set of log statements:
log " sending [HTTP::header username]"
log " sending [HTTP::header domain]"
log " sending [HTTP::header roles]"
All print out blank values. I have to refresh the page I am authenticating against to get those values to populate. This leads me to believe that I should be setting these values a bit earlier. Where should I start inserting these headers, to ensure the end application is getting them on every request?
I ended up ensuring that the headers are being set before the request is sent, using HTTP_REQUEST_SEND. Here is the working iRule:
when HTTP_REQUEST { insert clientless mode set apmsessionid [HTTP::cookie value MRHSession] if { [HTTP::cookie exists "MRHSession"] } { set apmstatus [ACCESS::session exists -state_allow $apmsessionid]} else {set apmstatus 0} if {!($apmstatus)} { Insert Clientless-mode header to start APM in clientless mode if { [catch {HTTP::header insert "clientless-mode" 1} ] } {log local0. "[IP::client_addr]:[TCP::client_port] : TCL error on HTTP header insert clientless-mode : URL : [HTTP::host][HTTP::path] - Headers : [HTTP::request]"} } } when HTTP_REQUEST_SEND { clientside { empty the current headers HTTP::header remove username HTTP::header remove domain HTTP::header remove roles set the headers needed for the application HTTP::header insert username [ACCESS::session data get session.custom.login] HTTP::header insert domain [ACCESS::session data get session.custom.domain] HTTP::header insert roles [ACCESS::session data get session.custom.roles] } } when ACCESS_POLICY_COMPLETED { Authentication request for non bowser user-agent session denied if { ([ACCESS::policy result] equals "deny") } { ACCESS::respond 401 noserver WWW-Authenticate "Basic realm=\"My Web Services Authentication\"" Connection close ACCESS::session remove return } else { set allRoles "" grab the session data containing the groups associated with the member set s [ACCESS::session data get "session.ad.last.attr.memberOf"] set matched [split [string map [list {| CN=} \0] $s] \0] foreach match $matched { if { $match != "" } { puts [string range $match 0 [expr [string first , $match] - 1]] set queryarray [split $match ","] set firstvalue [lindex $queryarray 0] set cleaneddata [string toupper [join $firstvalue _]] if { [string length allRoles] == 0 } { append allRoles "ROLE_$cleaneddata" } else { append allRoles ",ROLE_$cleaneddata" } } } puts $allRoles grab the session data containing the username associated with the member ACCESS::session data set session.custom.login [ACCESS::session data get "session.logon.last.logonname"] grab the session data containing the domaiin associated with the member ACCESS::session data set session.custom.domain [ACCESS::session data get "session.ad.last.actualdomain"] grab the session data containing the roles associated with the member ACCESS::session data set session.custom.roles $allRoles } }
- Yann_Desmarest_Nacreous
Hi,
I think that you can insert the header for the application in an ACCESS_ACL_ALLOWED event instead of HTTP_REQUEST :
when ACCESS_ACL_ALLOWED { empty the current headers HTTP::header remove username HTTP::header remove domain HTTP::header remove roles set the headers needed for the application HTTP::header insert username [ACCESS::session data get session.custom.login] HTTP::header insert domain [ACCESS::session data get session.custom.domain] HTTP::header insert roles [ACCESS::session data get session.custom.roles] log " sending [HTTP::header username]" log " sending [HTTP::header domain]" log " sending [HTTP::header roles]" }
Wiki page for this event : ACCESS_ACL_ALLOWED
This did not work for me, however, it does not mean it would not work for others. Possibly something to try. I did manager, however, to figure out a solution. Posting now
Hi,
I think that you can insert the header for the application in an ACCESS_ACL_ALLOWED event instead of HTTP_REQUEST :
when ACCESS_ACL_ALLOWED { empty the current headers HTTP::header remove username HTTP::header remove domain HTTP::header remove roles set the headers needed for the application HTTP::header insert username [ACCESS::session data get session.custom.login] HTTP::header insert domain [ACCESS::session data get session.custom.domain] HTTP::header insert roles [ACCESS::session data get session.custom.roles] log " sending [HTTP::header username]" log " sending [HTTP::header domain]" log " sending [HTTP::header roles]" }
Wiki page for this event : ACCESS_ACL_ALLOWED
This did not work for me, however, it does not mean it would not work for others. Possibly something to try. I did manager, however, to figure out a solution. Posting now
I ended up ensuring that the headers are being set before the request is sent, using HTTP_REQUEST_SEND. Here is the working iRule:
when HTTP_REQUEST { insert clientless mode set apmsessionid [HTTP::cookie value MRHSession] if { [HTTP::cookie exists "MRHSession"] } { set apmstatus [ACCESS::session exists -state_allow $apmsessionid]} else {set apmstatus 0} if {!($apmstatus)} { Insert Clientless-mode header to start APM in clientless mode if { [catch {HTTP::header insert "clientless-mode" 1} ] } {log local0. "[IP::client_addr]:[TCP::client_port] : TCL error on HTTP header insert clientless-mode : URL : [HTTP::host][HTTP::path] - Headers : [HTTP::request]"} } } when HTTP_REQUEST_SEND { clientside { empty the current headers HTTP::header remove username HTTP::header remove domain HTTP::header remove roles set the headers needed for the application HTTP::header insert username [ACCESS::session data get session.custom.login] HTTP::header insert domain [ACCESS::session data get session.custom.domain] HTTP::header insert roles [ACCESS::session data get session.custom.roles] } } when ACCESS_POLICY_COMPLETED { Authentication request for non bowser user-agent session denied if { ([ACCESS::policy result] equals "deny") } { ACCESS::respond 401 noserver WWW-Authenticate "Basic realm=\"My Web Services Authentication\"" Connection close ACCESS::session remove return } else { set allRoles "" grab the session data containing the groups associated with the member set s [ACCESS::session data get "session.ad.last.attr.memberOf"] set matched [split [string map [list {| CN=} \0] $s] \0] foreach match $matched { if { $match != "" } { puts [string range $match 0 [expr [string first , $match] - 1]] set queryarray [split $match ","] set firstvalue [lindex $queryarray 0] set cleaneddata [string toupper [join $firstvalue _]] if { [string length allRoles] == 0 } { append allRoles "ROLE_$cleaneddata" } else { append allRoles ",ROLE_$cleaneddata" } } } puts $allRoles grab the session data containing the username associated with the member ACCESS::session data set session.custom.login [ACCESS::session data get "session.logon.last.logonname"] grab the session data containing the domaiin associated with the member ACCESS::session data set session.custom.domain [ACCESS::session data get "session.ad.last.actualdomain"] grab the session data containing the roles associated with the member ACCESS::session data set session.custom.roles $allRoles } }
Recent Discussions
Related Content
* 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