Citrix NetScaler has features to provide SSO to web resources using the AAA-TM feature on the NetScaler. Organizations invested in XenApp and/or XenDesktop for providing secure remote access to virtual applications and desktops also leverage the NetScaler Gateway feature on the NetScaler to securely proxy ICA and SSO to Storefront/Web Interface to present applications and desktops after granularly controlling authentication, authorization and auditing at the NetScaler. Several organizations have a homepage in the form of the company website, a dashboard or at times even a MS SharePoint to present a portal to the company owned web resources. For providing secure remote access to this portal/dashboard, it is recommended that proper authentication is applied using the AAA-TM feature on the NetScaler. The configuration to achieve this has been outlined here:

This dashboard/portal also might include a link to the NetScaler Gateway which provides access to the virtual applications and desktops published via XenApp/XenDesktop. But since NetScaler Gateway requires separate external authentication before presenting the Storefront/Web Interface pages, users have to re-authenticate at the NetScaler Gateway login page.

The following steps describe the process to Single-Sign-On from an AAA-TM authenticated session to NetScaler Gateway to provide a seamless user experience.


1. Download tmindex.html to the computer. Note: Ensure that you back up this original file.
2. Open the file for editing with preferred document editor software.
3. Locate the following section of text. The line where this section is located will vary depending on the version of NetScaler:

Logon box –>
<tr class=”mainPane”>
<td class=”carbonBoxBottom” valign=”bottom”>
<script language=”javascript” type=”text/javascript”>
4. Insert the following text immediately after the section described in step 3 :

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(“login”, form.login.value);
setCookie(“passwd”, form.passwd.value);
return true;
5. The next two lines should read as follows:

name=”vpnForm” autocomplete=”off” style=”margin:0″

6. The HTML code should now read as follows:
<FORM method=”post” action=”/cgi/login” name=”vpnForm” autocomplete=”off” style=”margin:0″
onSubmit=”return storeValues(this); clean_name_cookie(this);”>
7. Make sure login and passwd cookies contain the username and password when the user authenticates at the AAA login page.

8. Config to login from AAA to AG when the user clicks on the AGEE page:

add responder action LOGIN_TO_AGEE_action respondwith “\”<html><head>\”+\”<script language=\\\”JavaScript\\\”>function UnsetCookie(cookieName) {document.cookie=cookieName+\\\”=nothing;expires=Thursday, 1 Jan 1970 00:00:00 GMT;; path=/\\\”;} </script>\”+\”<FORM action=\\\”\\\” method=\\\”post\\\” id=\\\”ctxredir\\\”>\n<INPUT type=\\\”login\\\” style=\\\”display:none\\\”\nname=\\\”login\\\” value=\\\”\”+ http.REQ.COOKIE.VALUE(\”login\”) + \”\\\”>\n<INPUT type=\\\”mypass\\\” style=\\\”display:none\\\”\nname=\\\”passwd\\\” value=\\\”\”+ http.REQ.COOKIE.VALUE(\”passwd\”) + \”\\\”></FORM><script language=\\\”JavaScript\\\” type=\\\”text/javascript\\\”>\n<!–\ndocument.getElementById(\\\”ctxredir\\\”).submit();\n//–>\n</script>\”+\”</head></html>\”” -bypassSafetyCheck YES

add responder policy “http.REQ.HOSTNAME.EQ(\”\”) && (http.REQ.URL.EQ(\”/\”) || http.REQ.URL.EQ(\”/cgi/login\”) || http.REQ.URL.EQ(\”/vpn/index.html\”)) && http.REQ.HEADER(\”Cookie\”).CONTAINS(\”login\”)” LOGIN_TO_AGEE_action
bind responder global 100 END -type REQ_OVERRIDE


Please note that the login and passwd cookies can be re-encrypted and secured as described in the following blog: /blogs/2011/08/05/secure-your-application-cookies-before-it-is-too-late/.


The sample code available in this article is provided as is with no representations, warranties or conditions of any kind. You may use, modify and distribute it at your own risk. CITRIX DISCLAIMS ALL WARRANTIES WHATSOEVER, EXPRESS, IMPLIED, WRITTEN, ORAL OR STATUTORY, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NONINFRINGEMENT. Without limiting the generality of the foregoing, you acknowledge and agree that (a) the sample code may exhibit errors, design flaws or other problems, possibly resulting in loss of data or damage to property; (b) it may not be possible to make the sample code fully functional; and (c) Citrix may, without notice or liability to you, cease to make available the current version and/or any future versions of the sample code. In no event should the code be used to support of ultra-hazardous activities, including but not limited to life support or blasting activities. NEITHER CITRIX NOR ITS AFFILIATES OR AGENTS WILL BE LIABLE, UNDER BREACH OF CONTRACT OR ANY OTHER THEORY OF LIABILITY, FOR ANY DAMAGES WHATSOEVER ARISING FROM USE OF THE SAMPLE CODE, INCLUDING WITHOUT LIMITATION DIRECT, SPECIAL, INCIDENTAL, PUNITIVE, CONSEQUENTIAL OR OTHER DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Although the copyright in the code belongs to Citrix, any distribution of the code should include only your own standard copyright attribution, and not that of Citrix. You agree to indemnify and defend Citrix against any and all claims arising from your use, modification or distribution of the code.