This post covers the configuration needed to provide your users with the possibility to multiple cookie-based authentication methods through Netscaler 10.1 and above (like 10.5).
Citrix do have a CTX article that covers basically the same thing but the configuration steps provided are not valid anymore due to some modifications on logon index.htlm file on the Netscaler box since the introduction of Netscaler firmware 10.1.

So, Let’s suppose you would like to give your users the possibility to authenticate using two methods:

  • SMS PASSCODE (Two factor)
  • LDAP (One factor)

Here follows the instructions needed:

  • Create a cookie on the computer of the user
  • Create a drop-down menu
  • Create a procedure to allow the custom page to survive a reboot
  • Modify the authentication profiles to be based on the presence of the cookie instead of the default true value

Configuration applicable to Netscaler 10.1 and 10.5

Create a cookie on the computer of the user

To create a cookie on the computer of the user, complete the following procedure:
The name of the cookie we will use is cookievalue and it is created to store the name of the authentication method chosen from the drop-down menu.

  • Use WinSCP to browse your Netscaler box and Open the file index.html for editing, located at “/netscaler/ns_gui/vpn” directory. (Backup the file before doing any modifications).
  • Locate the following section (should be located at the beginning of the index.html file):

</SCRIPT>
<script language=”javascript” type=”text/javascript” src=”/vpn/nsshare.js”></script>
<script language=”JavaScript” type=”text/javascript” src=”login.js”></script>
<SCRIPT language=JavaScript>

  • Add the following code above the located section in previous step.

<SCRIPT type=”text/javascript”>
function getCookie(name) { // use: getCookie(“name”);
var re = new RegExp(name + “=([^;]+)”);
var value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
}
var today = new Date();
var expiry = new Date(today.getTime() + 28 * 24 * 3600 * 1000); // plus 28 days
var expired = new Date(today.getTime() – 24 * 3600 * 1000); // less 24 hours
function setCookie(name, value) { // use: setCookie(“name”, value);
document.cookie=name + “=” + escape(value) + “; path=/; expires=” + expiry.toGMTString();
}
function storeValues(form) {
setCookie(“cookievalue”, form.cookievalue.value);
return true;
}

  • Now look for the following line:

<FORM method=”post” action=”/cgi/login” name=”vpnForm” autocomplete=”off” style=”margin:0″ onSubmit=”return clean_name_cookie(this);>

and add “storeValues(this);” so the line looks exactly like the following:

<FORM method=”post” action=”/cgi/login” name=”vpnForm” autocomplete=”off” style=”margin:0″ onSubmit=”return storeValues(this); clean_name_cookie(this);”>

Create the drop-down menu

To create a drop-down menu, complete the following procedure:

  • On the same index.html page, locate the following lines:

    <SCRIPT language=JavaScript>ns_showpwd_greenbubble();</SCRIPT>
    <script language=’javascript’>ns_disperrmsg();</script>

  • Now, Add the following lines immediately after the located ones in the step above:

    <div class=”field buttons”>
    <div class=”left”><label class=”label plain”>Method:</label></div>
    <div class=”right”>
    <select name=”cookievalue” size=”1″ style=”width: 200px;”>
    <option value=”SMSPASSCODE”>SMSPASSCODE</option>
    <option value=”LDAP”>LDAP</option>
    </select>
    </div>
    </div>

    Note: SMSPASSCODE & LDAP must be replaced with the names you prefer. You can add as many values as you want here.

  • Save the changes and the drop down part is done and should look something similar to this:

logonpage-ag

 

 

 

 

 

 

Create a procedure to ensure that the Custom Page endures a restart

To create a procedure to ensure that the custom page endures a restart, complete the steps from this post

Modify the authentication profiles to be based on the presence of the cookie instead of the default true value (ns_true)

To modify the authentication profile to be based on the presence of the cookie instead of the default “true-value”, ensure that the expression syntax is similar to the configuration, as shown in the following screen shot and do not forget the right cascading order when linking those to the AGVIP:

ldap-poli

 

 

 

auth-pol

 

 

 

 

 

 

 

 

auth-pol-rec

 

 

 

 

 

 

 

Configuration applicable for Netscaler 11 and above

Things are getting much more easier with latest Netscaler releases. Basically two simple steps are required to achieve what we are looking for.
First of all we need to create a rewrite policy in order to send the domain data to the clients, second and last step requires modification of your authentication profile to be based on the presence of the cookie instead of the default true value…

The client needs to know which are the available domains that need to be shown to the user. This information is passed in a secure cookie. The rewrite feature of NetScaler can help send a SET-Cookie header with this information.

Start by creating a rewrite action:

add rewrite action insert_authentication_dropdown_action insert_http_header Set-Cookie “\”authMethods=SMSPasscode,LDAPS,AzureMFA,Vasco;path=/;Secure\””The authentication methods can be given in a similar fashion shown as above separated by comma(,). Here “authMethods” is the name of the cookie which will pass this information.

add rewrite policy insert_authentication_dropdown_policy “HTTP.REQ.URL.CONTAINS(\”/vpn/index.html\”)” insert_authentication_dropdown_actionThis will add a policy which trigger on the login page and enforce the above action.

bind vpn vserver “name-of-your-agvip” -policy insert_authentication_dropdown_policy -priority 100 -gotoPriorityExpression END -type RESPONSEThis will bind the above policy to the vserver for which the configured domains need to come up

Now we need to tweak the authentication profile so that we can choose the correct profile based on the selection of domain made by the end user.

To modify the authentication profile to be based on the presence of the cookie instead of the default “true-value”, ensure that the expression syntax looks like the following:

REQ.HTTP.HEADER Cookie CONTAINS SMSPasscode
REQ.HTTP.HEADER Cookie CONTAINS LDAPS
REQ.HTTP.HEADER Cookie CONTAINS AzureMFA
REQ.HTTP.HEADER Cookie CONTAINS Vasco