Forum Discussion
clientless-mode, session-cookie and policy re-evaluation
Hi Everyone,
I am trying to use the inbuilt OTP functions within APM, so that they can be consumed by other systems that want to use OTP.
I have managed to use clientless-mode and have a system connect and execute the policy branch based on a specific URI and also pass header variables to choose if to generate or verify OTP. The session also return the MRHSession cookie so that this can be used to connect back to the same session, to do OTP verification.
The issue i am having is that when I connect back to the APm using an existing session (using the MRHsession cookie) i get a 504 received failure. I assume this is because when you connect back using a cookie the APM policy is not run again.
How can i get the policy to run again so that i can perform an OTP verification, based on a known SessionID?
7 Replies
- Stanislas_Piro2
Cumulonimbus
Hi,
clientless mode is a dedicated mode to authenticate user in one request.
the session status must be Allow or deny at the end of the session.
OTP password must be entered within the session.
I'm not sure you can use OTP with clientless mode. you can try SWG-explicit profile type instead of clientless mode (SWG-explicit profile enter in a kind of clientless mode, but supporting ip source based session)
- Posterus_85681
Nimbostratus
Hi Stan,
This is what i have done to get around the issues you mentioned above. It works, but i don't know if its the most efficient way to do it or if it can be improved. I can come back into the same access session by presenting a cookie (this is how i execute the OTP verification)
when HTTP_REQUEST { HTTP::header insert "clientless-mode" 1
set otp_generated [ACCESS::session data get "session.otp.assigned.val"] set otp_to_verify [HTTP::header otp] set otp_status "failed" if { ($otp_to_verify) equals ($otp_generated) } { set otp_status "success" } if { ([HTTP::header otpmode] equals "generate") }{} if { ([HTTP::header otpmode] equals "verify") } { HTTP::respond 200 otp_status $otp_status Connection Close }}
when ACCESS_SESSION_STARTED { ACCESS::session data set "session.custom.otpmode" [string trim [HTTP::header otpmode]] }
when ACCESS_POLICY_COMPLETED { ACCESS::respond 200 OTP [ACCESS::session data get "session.otp.assigned.val"] SID [ACCESS::session data get "session.user.sessionid"] Connection Close } }
- Stanislas_Piro2
Cumulonimbus
Hi,
when ACCESS_POLICY_COMPLETED is raised, you cannot reevaluate the policy.
if you want to execute a irule in the policy evaluation, you can raise ACCESS_POLICY_AGENT_EVENT event:
when ACCESS_POLICY_AGENT_EVENT { if {[ACCESS::policy agent_id] == "otp"} { ACCESS::respond 200 OTP [ACCESS::session data get "session.otp.assigned.val"] SID [ACCESS::session data get "session.user.sessionid"] Connection Close } }In ACCESS_POLICY_COMPLETED event, filter answer with Access policy result:
when ACCESS_POLICY_COMPLETED { Authentication request for non bowser user-agent session denied if { ([ACCESS::policy result] equals "deny") } { ... } } - Posterus_85681
Nimbostratus
Hi Everyone,
I think this needs a bit of clarification. I have managed to make the F5 APM work like a web services API, so that other external systems can utilise the built in OTP generation/verficiation. I will show the code and how it works below. I would like some feedback as to how i could improve it (if it can be improved).
HOW IT WORKS
GENERATE OTP CODE
External System --> (calls) F5 APM (using a HTTPS POST) and passing a header variable "otpmode", that is used to select if the ext system wants to generate or verify the otp code.
POST https://fqdn.com/otp HTTP/1.1 User-Agent: Fiddler Host: fqdn.com Content-Length: 0 otpmode: generateA response is then received as follows, with a header variable "otp" which is the OTP code generated in the F5 APM and also gets returned the cookie for the APM session. This OTP code can then be used by the external system (send via email or SMS for user/other to use)
HTTP/1.0 200 OK OTP: 623177 SID: xxxxx Server: BigIP Connection: Close Set-Cookie: LastMRH_Session=xxxxx;path=/;secure Set-Cookie: MRHSession=xxxxx;path=/;secure Content-Length: 0VERIFY OTP CODE
External System --> (calls) F5 APM (using a HTTPS POST) and passing a header variable "otpmode", that is used to select if the ext system wants to generate or verify the otp code (in this case verify) and the OTP code that needs to be verified. It also passes the cookie so the system rejoins to the APM session it created in the generation activity.
POST https://fqdn.com/otp HTTP/1.1 User-Agent: Fiddler Host: fqdn.com Content-Length: 0 otpmode: verify otp: 536484 Cookie: MRHSession=xxxxx;path=/;secureA response is then received telling the ext system if the code sent for verification is correct.
HTTP/1.0 200 OK OTP_status: success Server: BigIP Connection: Close Set-Cookie: LastMRH_Session=xxxxx;path=/;secure Set-Cookie: MRHSession=xxxxx;path=/;secure Content-Length: 0CODE TO MAKE THIS WORK
iRULE
when HTTP_REQUEST { HTTP::header insert "clientless-mode" 1 set otp_generated [ACCESS::session data get "session.otp.assigned.val"] set otp_to_verify [HTTP::header otp] set otp_status "failed" if { ($otp_to_verify) equals ($otp_generated) } { set otp_status "success" } if { ([HTTP::header otpmode] equals "generate") }{} if { ([HTTP::header otpmode] equals "verify") } { HTTP::respond 200 otp_status $otp_status Connection Close }} when ACCESS_SESSION_STARTED { ACCESS::session data set "session.custom.otpmode" [string trim [HTTP::header otpmode]] } when ACCESS_POLICY_COMPLETED { ACCESS::respond 200 OTP [ACCESS::session data get "session.otp.assigned.val"] SID [ACCESS::session data get "session.user.sessionid"] Connection Close } } }APM POLICY
The APM policy is basically as follows:
-> Blank Box, which looks at "optmode" and selects branch as either "generate" or "verify" -> "Generate" branch then goes to "OTP Generate" -> faallback -> Allow -> "Verify" branch then goes to "OTP verify" -> Success or Fallback -> Allow - Stanislas_Piro2
Cumulonimbus
So, does it work???
APM session cannot be re-evaluated... if you want to store OTP password, you can create a table value in the generate branch and read it in the verify branch:
when ACCESS_POLICY_AGENT_EVENT { switch -glob [string tolower [HTTP::header "User-Agent"]] { "otpgenerate" { table add -subtable "OTP" [ACCESS::session data get "session.logon.last.username"] [ACCESS::session data get "session.otp.assigned.val"] indef 60 } "otpverify" { ACCESS::session data set "session.otp.assigned.val" [table lookup -subtable "OTP" [ACCESS::session data get "session.logon.last.username"]] } } }you must add irule event boxes in the VPE to raise this irule with IDs otpgenerate or otpverify.
- Posterus_85681
Nimbostratus
It does work. Because the APM policy can not be re-evaluated thats why we connect back with MRH cookie and then compare the OTP code to verify from the ext system via header variable and compare this to the session.otp.assigned.val value that was generated (this is done in the http request section)
- Stanislas_Piro2
Cumulonimbus
When I look in your configuration, everything is allowed... there is no reject if the OTP code is wrong or the client does not provide a OTP code. If the first request contains generate, the APM allow the connection... if in the following requests, there is no generate or verify, the irule allow connection. the decision to allow or not the connection is not made by APM but by the client which receive the OTP status.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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