Form Based SSO for Dynamically built HTTP forms

Problem this snippet solves:

This snippet solves a challenge where Client Initiated Form Based SSO is required but you have no available trigger that you can configure to allow APM to detect the form.

This is typically something you can face when you try to configure SSO Forms for some version of the Citrix Storefront Web UI. when digging in the html and javascript, you can see that a single Javascript build the HTML content and thus the forms, so no ways to detect the form when data are in transit.

How to use this snippet:

You have to install a single irule on the Virtual Server protecting the web application. This irule use ACCESS commands so assuming you have APM and an access profile is attached to the Virtual Server.

Code :

    if { [ACCESS::policy result] eq "allow" } {
        if { [HTTP::path] ends_with “/Citrix/Company/ExplicitAuth/LoginAttempt" and [HTTP::method] eq "POST" } {
            HTTP::collect [HTTP::header Content-Length]
        if { [HTTP::path] ends_with "/Citrix/Company/" } {
            set var 1

    set payload [HTTP::payload]
    set newpayload [string map [list "f5-sso-token" "[ACCESS::session data get -secure session.sso.token.last.password]"] $payload]
    HTTP::payload replace 0 [string length $payload] $newpayload

    if { [info exists var] and $var } {
        HTTP::collect [HTTP::header values "Content-Length"]

    set payload [HTTP::payload]
    set username [ACCESS::session data get session.sso.token.last.username]
    set password "f5-sso-token"
    set sso ""
    ### This code requires JQuery. Uncomment those lines if you need to load the library
    # set jquery "" 
    # set newpayload [string map [list "" $jquery] $payload]
    ### END

    set newpayload [string map [list "" $sso] $payload]  
    HTTP::payload replace 0 [string length $payload] $newpayload


Tested this on version:

Published Oct 16, 2018
Version 1.0

Was this article helpful?


  • Hi Yann, thanks for sharing this. It came to good use today. However, I had to make one small adjustment. It had to do with jQuery. I had to include the jQuery library, because the website didn't use jQuery. See below an example of the changes I made to the HTTP_RESPONSE_DATE event.

    set jquery "" 
    set newpayload [string map [list "" $jquery] $payload]
    set newpayload [string map [list "" $sso] $newpayload]
  • Hi Niels,


    Good point


    Thank you for your feedback. Indeed, the script has been built for Citrix Storefront and thus JQuery was already loaded.


    I will update the original content with your code.


    Thanks again for your help






  • Hi Yann, thanks for updating. I stumbled into another error. An user was using the ampersand character in the password. The solution in this case was to use

    the password. The client was already sending the
    Content-Type: application/x-www-form-urlencoded
    header, so there was no need to add this header. See the changes in the HTTP_REQUEST_DATA event below.

    set password [URI::encode [ACCESS::session data get -secure session.sso.token.last.password]]
    set newpayload [string map [list "f5-sso-token" $password] $payload]
  • Nice finding Niels. Indeed, I forget to manage this use case. My mistake.


    I will update the code shortly to integrate your fix.