I decorate my own cookie…dual authentication policies on Netscaler

Edit September 10th, 2015: Be aware of one thing if you plan to use the native Citrix Receiver to access applications: The workaround described in this article will break authentication for native Receiver. If you need both LDAP and RADIUS authentication, it might be better to remove the checkmark for “Authentication” in the LDAP profile. This makes the Password field disappear, but you can still use LDAP for password change and group extraction.


When configuring user authentication for Netscaler Gateway or other services on Netscaler, I usually rely on only one type of authentication at a time. Since most New customers want’s to use two-factor authentication with SMS One TIme Passcodes (OTP), this mostly means that I configure a RADIUS authentication policy, using SMS Passcode. The challenge rises when they want to be able to change passwords via Netscaler and Storefront, either because it’s required, or that they simply want to. So far I haven’t been able to figure out how to facilitate this via RADIUS, so the only option is to do this via LDAPS (http://support.citrix.com/article/CTX122972, Acccess Gateway 9.2 or later for version 10.x). The caveat with this approach, is that it adds a second password field on the user login page. This is quite alright when you use old-fashion RSA or other two-factor authentication methords that relies on user-held tokens that gives out OTPs, because then the user enters both the password and the OTP at the same time when logging on. SMS Passcode and other SMS-based solutions usually doesn’t send this code until after the user has entered his/her username and passord, rendering the second password Field unusable…and confusing. The solutions that I have seen so far, has involved changing the original source files on the netscaler, like logins.js, to hardcode only one password field regardless of the configuration. I’ve never really liked this approach, because it happens behind the scene, and can be a complication when it comes to upgrading the Netscaler later on. Not my favourite thing… So, I decided to find a better way! I had been looking in to using rewrite and responder for a while to fix fhis, but only came as far as getting to change the text label of the password field. Not quit what I needed. Then I spent som time examining the code in login.js (/netscaler/ns_gui/vpn/login.js), and I realized that they use a cookie to check the number of authentication Methods, one or two. The cookie is named pwcount. The contents, or rather value,  of this cookie is assigned to the variable pwc. The this variable is checked, and if the value equals 2, the second password field is visible. My simple solution: create a rewrite policy the overrides the pwcount cookie value, and always sets it to 1. Then this policy is bound to a vserver (or virtual Access Gateway) or globally on the Netscaler.

The highlighted text shows where the pwc variabel is set to the value of the pwcount cookie, and that it's checked for value.

The highlighted text shows where the pwc variabel is set to the value of the pwcount cookie, and that it’s checked for value.

The rewrite is set up as follows: Create a Rewrite Action, set the type to INSERT_HTTP_HEADER. Header Name is Set-Cookie. The Expression is “pwcount=” + 1 (this sets the value of the pwcounts cookie).

The rewrite action

The rewrite action

The policy is as follows: Action is Rewrite_PwCount (the one made above). Log Action is not set, Undefined-Result Action is set to – Global-undefined-result-action-. Expression: HTTP.REQ.HEADER(“Cookie”).CONTAINS(“pwcount”).NOT

The rewrite policy

The rewrite policy

Bind this as a Rewrite policy on the vserver. NB: On Netscaler 10.x (and maybe older), note that it should be bound as a Responder policy. The change will be effective immediately. If you need to troubleshoot this, I recommend using Firefox and the Firebug addon. That gives you easy access to cookies contents, and also allows you to add cookies or change contents at will to debug and test stuff like this. I have testet this method on Netscaler 10.1 and 10.5. It should work fine on 9.x as well. The thing to look for here, is the cookie reference in login.js. As long as you can change the value of that, you should be fine.


19 thoughts on “I decorate my own cookie…dual authentication policies on Netscaler

  1. Robert

    I tested you solution yesterday, this works perfectly however when you allow users to change their password with ldaps or when the password is expired or the option user must change password at next logon is set in AD the user can’t login.

    1. geirrs Post author


      This usually happens because there are multiple domain controllers in the domain, and they are situated in different sites. Password changes aren’t necessarily replicated across sites immediately after it’s changed, and if the user then tries to logon with new password and gets authenticated on a different DC, the logon will fail.

      1. Robert


        This is just a single site with only two domain controllers.
        Normally if the password is expired or set to: user must change password at next logon, you can logon and you need to change your password and log back in again.

      2. geirrs Post author

        This should be the same in your scenario. After the password is changed, the user must log in again via Netscaler. Which authorization profile is set as primary on your Netscaler? The LDAP profile should be set as secondary, and the RADIUS as primary.

  2. Robert

    I don’t get the option to change the password.

    I have set LDAP as primary authentication policy and OTP as secondary.
    Will change this and let you know the results.

    1. geirrs Post author

      Ok. In the LDAP remember to change the protocol to “TLS”. You can then confirm that the “Allow password change” option is available and enabled.
      Also, if you use Storefront in the backend, rememeber to allow password change there, in Authentication.

      1. Robert

        Tested the configuration tonight and it works !

        Set the LDAPS as primary authentication policy on the Netscaler Gateway and the OTP as the secondary authentication policy.
        Now when i logon the system prompts that the password is expired and must be changed.

        Maybe you can add this to your article.

      2. geirrs Post author

        Nice to hear that it works. 🙂 I am planning to do an article on how to setup dual authentication that supports password changes, so it will be described in detail then. The purpose for this article was to show how to hide the second password field without having to rewrite the files themselves. I prefer to do it with rules and configuration rather than hacking it. 😛
        Welcome back later, and thanks for commenting! Feel free to “like” my Facebook page as well at https://www.facebook.com/sysconsultants, and tell your friends about it. If there are any other questions, you can put them there and I will try to answer them.

  3. Neo

    This works perfect when I use the web interface. But it causes Citrix Receiver for Windows to stop functioning. When I try to logon directly with Receiver (4.2) I get the following error in AuthManLog.txt:
    Exception type: Protocol exception
    Detail: The gateway response did not contain the expected cookie (pwcount)

    1. geirrs Post author

      I suggest that you try to change the expression, so that it only applies to users logging in via Receiver for Web. That can be done by checking the user agent header.

  4. Gopi Bhaktha

    For some reason this expression doesnt work for me “pwcount=” +1 expression syntax error. How do i build this expression editor?

  5. Jacob hoepfner

    your Edit of September 10th, 2015 regarding unchecking ‘authentication’ doesn’t work for me.
    When unchecked I can’t make password changes work.
    However your Set-Cookie works brilliantly and Citrix has finally provided a fix for Receiver as well:
    The fix involves editing the index.html file though, which I’m not really satisfied with, so I now use a combo of your rewrite and my own rewrite for the Receiver.

    To avoid breaking Receiver put a filter in the Set-Cookie Rewrite policy:
    add rewrite policy RW_POL_remove_pw2_web “HTTP.REQ.HEADER(\”Cookie\”).CONTAINS(\”pwcount\”).NOT && HTTP.REQ.HEADER(\”User-Agent\”).CONTAINS(\”CitrixReceiver\”).NOT” RW_ACT_remove_pw2_web

    And for Receiver access create an RW action and policy:
    add rewrite action RW_ACT_remove_pw2_receiver insert_after_all “http.res.body(1024)” q/”\r\n”+””/ -pattern “content=\”text/html; charset=UTF-8\”>”

    add rewrite policy RW_POL_remove_pw2_Receiver “http.req.url.path.endswith(\”vpn/index.html\”)” RW_ACT_remove_pw2_receiver

  6. Jacob hoepfner

    Oops – sorry, the rw action was a little short there – should be:

    add rewrite action RW_ACT_remove_pw2_receiver insert_after_all “http.res.body(1024)” q/”\r\n”+””/ -pattern “content=\”text/html; charset=UTF-8\”>”

  7. Jacob hoepfner

    ??? again ???
    not sure what is happening, but the important part is cut out when I paste it – guess the reply field doesn’t like escape chars ?
    after \r\n”+” “/


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s