This method is not compatible with NetScaler version 11.0 after build 64.34 since Citrix deprecated the -userdomains vpn vserver parameter. Please see http://support.citrix.com/article/CTX203873 for alternate instructions.
Thanks to Scott Osborne (@VirtualOzzy) for pointing this out to the CUG Networking SIG
When NetScaler 11.0 was released I noticed a couple of interesting things
1. There was a new ‘userdomains’ parameter for VPN virtual servers.
2. ‘gateway_login_form_view.js’, used to write the NetScaler Gateway login form as of version 11.0, contained the following:
I had hoped that this meant that Citrix had built in support for creating multi domain drop downs for NetScaler Gateway virtual servers out of the box with version 11.0. unfortunately this isn’t the case with NetScaler Gateway but it is with AAA virtual servers which now support NFactor authentication (Thanks @NSTipster for the clue!)
Anyway, as much as I appreciate NFactor for AAA virtual servers that was not my goal so I went implementing for NetScaler Gateway.
When’ playing with the userdomains parameter I noticed that setting this adds the domains to a cookie called ‘userDomains’
setting userdomains per vserver:
Cookie created as a result of setting userdomains parameter:
although out of the box this changes nothing for the end user when browsing the NetScaler gateway login page it does give us an interesting opportunity. We can use this cookie to populate our custom drop down menu rather then hard coding into the customized pages. Much nicer.
we only need to make a couple of changes to gateway_login_form_view.js to bring the preexisting create_drop_down function to life:
Firstly I’ve copied the default gateway_login_form_view.js so we can modify a new file
From shell:
cp /netscaler/ns_gui/vpn/js/gateway_login_form_view.js /netscaler/ns_gui/vpn/js/gateway_login_form_view_domains.js
create a rewrite policy to load this new ‘gateway_login_form_view_domains.js’ rather then the default ‘gateway_login_form_view.js’ when /vpn/index.html is loaded.
From NS CLI:
add rewrite action ReAct_domains_form_view replace_all “HTTP.RES.BODY(120000)” q{“<script type=\”text/javascript\” src=\”/vpn/js/gateway_login_form_view_domains.js\”></script>”} -search q{text(“<script type=\”text/javascript\” src=\”/vpn/js/gateway_login_form_view.js\”></script>”)}
ReAct_getcookie_userdomains
add rewrite policy RePol_domains_form_view “HTTP.REQ.URL.EQ(\”/vpn/index.html\”)” ReAct_domains_form_view
find the following line:
var domain = ns_getcookie(“domain”);
change it to:
var domain = ns_getcookie(“userDomains”);
This will present you with a drop down, albeit ugly and unpopulated with end user readable text
if you inspect the newly generated element you’ll see the userdomains you set previously are present in the code however the option text parameter has not been set.
Find the following line:
var select = $(‘<select name=”domainvalue”></select>’).attr({“size”:”1″,”class”:”domain_select”});
Change it to:
var select = $(‘<select name=”domainvalue”></select>’).attr({“size”:”1″,”class”:”domain_select”,”style”:”width: 360px; height: 40px”});
Find the following line:
var option = $(“<option></option>”).attr({“value”:domains[j],”id”:domains[j]});
change it to:
var option = $(“<option></option>”).attr({“value”:domains[j],”id”:domains[j],”text”:domains[j],”style”:”width: 360px; height: 40px”});
Much better.. but at the moment still useless until we can use this selection in an expression that can be attached to an authentication policy. In order to see what this could be we check what happens when we submit a login request with a domain selected from the drop down menu
Now if advance HTTP expressions should be used on NetScaler Gateway authentication policies we would have a winner here as we could apply a policy based on the domainvalue value in the HTTP request body but unfortunately we cannot with NetScaler Gateway
back to the old school method of setting a cookie using the drop down menu then.
Find the following line:
//domain drop down markup
Insert the following before it (line 41):
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(“domainvalue”, form.domainvalue.value);
return true;
}
Find the following line:
var form = $(“<form></form>”).attr({method:’post’,action: action_url ,name:’vpnForm’,autocomplete:’off’, style : ‘magin:0’}).submit(function(event){clean_name_cookie();ns_check(event);});
Insert the following before it (line 41):
var form = $(“<form></form>”).attr({method:’post’,action: action_url ,name:’vpnForm’,autocomplete:’off’, style : ‘magin:0’}).submit(function(event){return storeValues(this);clean_name_cookie();ns_check(event);});
From the NS CLI create an LDAP authentication policy for each domain you wish to authenticate against – in my case lab, stuartc and stuc:
add authentication ldapPolicy AuthPol_LDAP_lab_Users “REQ.HTTP.HEADER Cookie CONTAINS domainvalue=lab” AuthSrv_LDAP_lab_Users
add authentication ldapPolicy AuthPol_LDAP_stuartc_Users “REQ.HTTP.HEADER Cookie CONTAINS domainvalue=stuartc” AuthSrv_LDAP_stuartc_Users
add authentication ldapPolicy AuthPol_LDAP_stuc_Users “REQ.HTTP.HEADER Cookie CONTAINS domainvalue=stuc” AuthSrv_LDAP_stuc_Users
Bind the above policies to your NetScaler gateway virtual server and there you go, authentication to multiple domains from a single NetScaler Gateway using a drop down menu.
Hopefully it wont be long till NFactor is supported on NetScaler Gateway, until then hope this helps someone.
The modified gateway_login_form_view.js can be downloaded here
[…] Great content by Stuart Carroll as he talks about the use of multiple domains (dropdown menu) in the latest NetScaler 11 release: http://www.stuartc.net/blog/tech/netscaler-gateway-11-0-multi-domain-dropdown/ […]