Choosing ”HTML5 Receiver” vs ”Native Receiver” dynamically through Netscaler Rewrite Policies
After a user has authenticated on a NSGW vServer, the user will either be prompted to select which Receiver Type (HTML5 vs Native) he/she wants to use, or a choice will be made automatically depending on how well the user’s web browser manages to detect a local Citrix Receiver install. See below picture for an example of the prompt I’m referring to.
You can however get rid of below prompt, and at the same also have a mechanism that selects which Receiver Type that should be for a particular user or scenario. This is achieved through Netscaler Rewrite policies.
How does it work?
In a normal scenario, after the Receiver Type has been selected (either automatically or by user), then the cookie ’CtxsClientDetectionDone=true’ will be created in the user’s web browser. If Native Receiver has been chosen, then the cookie ’CtxsUserPreferredClient=Native’ will also be created. By using Rewrite Policies we can create these two cookies by ourselves for the user, and therefore suppress the prompt for the user and automatically choose which Receiver Type to use.
If HTML5 should be used, then we only want to apply the Rerwite policy ”RWP-RES-DISABLE-RECEIVER-CHECK” to suppress the prompt. When Netscaler sees that the cookie ’CtxsUserPreferredClient’ Cookie is missing, it will default to HTML5 Receiver (this is dependent on your Storefront configuration – see further down). If we want to force the Native Receiver, we also apply the rewrite policy RWP-RES-SET-NATIVE-RECEIVER” to create the cookie ’CtxsUserPreferredClient=Native’.
In below scenario, I have defined an Expression for my Rewrite Policy ’RWP-RES-SET-NATIVE-RECEIVER’ to only apply if the user is connecting from IP subnet 10.240.5.0/24. You can also use ”HTTP.REQ.HEADER(\”User-Agent\”).CONTAINS(\”Chrome\”)” to only apply it to Chrome Users, or use most other type of Expressions. I tried to use HTTP.REQ.USER.ATTRIBUTE(1) and HTTP.REQ.USER.IS_MEMBEROF(\”GroupName\”) expressions, but it seems that these expressions will always evaluate to false for a Rewrite Policy bound to a VPN vServer, so they don’t work, which is a shame.
<strong>add rewrite action RWA-RES-DISABLE-RECEIVER-CHECK insert_http_header Set-Cookie "\"CtxsClientDetectionDone=true\""
add rewrite action RWA-RES-SET-NATIVE-RECEIVER insert_http_header Set-Cookie "\"CtxsUserPreferredClient=Native\""
add rewrite policy RWP-RES-DISABLE-RECEIVER-CHECK "HTTP.REQ.HOSTNAME.SERVER.SET_TEXT_MODE(IGNORECASE).EQ(\"login.mycompany.com\")" RWA-RES-DISABLE-RECEIVER-CHECK
add rewrite policy RWP-RES-SET-NATIVE-RECEIVER "HTTP.REQ.HOSTNAME.SERVER.SET_TEXT_MODE(IGNORECASE).EQ(\"login.mycompany.com\") && CLIENT.IP.SRC.IN_SUBNET(10.240.5.0/24)" RWA-RES-SET-NATIVE-RECEIVER
add vpn vserver NSGW-LOGON_STAR.MYCOMPANY.COM SSL 220.127.116.11 443 -appflowLog DISABLED
bind vpn vserver NSGW-LOGON_STAR.MYCOMPANY.COM -staServer "http://mySTA2.mycompany.local"
bind vpn vserver NSGW-LOGON_STAR.MYCOMPANY.COM -staServer "http://mySTA1.mycompany.local"
bind vpn vserver NSGW-LOGON_STAR.MYCOMPANY.COM -policy NSGW-AP-LDAP -priority 100
bind ssl vserver NSGW-LOGON_STAR.MYCOMPANY.COM -certkeyName star.mycompany.com
bind vpn vserver NSGW-AP-LOGON_STAR.MYCOMPANY.COM -portaltheme RfWebUI
<strong>bind vpn vserver NSGW-AP-LOGON_STAR.MYCOMPANY.COM -policy RWP-RES-DISABLE-RECEIVER-CHECK -priority 110 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver NSGW-AP-LOGON_STAR.MYCOMPANY.COM -policy RWP-RES-SET-NATIVE-RECEIVER -priority 120 -gotoPriorityExpression NEXT -type RESPONSE</strong>
For the choice between Native Receiver and HTML5 Receiver to work, you will need to configure your Storefront so that both HTML5 and Native Receivers are possible, like below picture. If you configure ”Always use Receiver for HTML5” instead of ”Use Receiver for HTML5 if local Receiver is unavailable”, then it doesn’t matter that the cookie ’CtxsUserPreferredClient=Native’ exists. Similarly, if you configure ”Install locally” instead of ”Use Receiver for HTML5 if local Receiver is unavailable”, then Native Receiver will always be used.
If you want want the dynamic choice between HTML5 and Native Receiver, then don’t use ”Use Receiver for HTML5 if local Receiver is unavailable” and only create the ’CtxsClientDetectionDone’ cookie to suppress the unnecessary prompt for the user.
Feel free to email me at firstname.lastname@example.org if you have any suggestions or questions related to this blog post.