Jump to content
Welcome to our new Citrix community!

Unable to distinguish Web from Gateway Plug-in request to Unified Gateway

Recommended Posts

I am implementing Cisco Duo 2FA for NetScaler Gateway. 


The iFrame from Duo (for in-line enrollment and 2FA selection) works great for the web traffic, however fails at Duo scrips when using the Gateway Plug-in w/o first initiating the web session.


The iFrame can be skipped by sending an auto-push to the client's Duo enrolled device - eliminating the best features of Duo (the inline enrollment and 2FA selection).


I have a Duo RADIUS server working for each of these two scenarios.


however I am unable to distinguish the one scenario/client from the other to send authentication to the corresponding Authentication server.


The goal is to have user sessions launched from a browser to authenticate to RADIUS(1) supporting Duo’s iFrame. User sessions launched from the Plug-in (from Windows system tray) to authenticate to RADIUS(2) supporting Duo’s auto-push and NOT the iFrame.

Note that I have confirmed that both RADIUS servers function when tested in their respective use-cases.


I have use policy expressions below to no avail:


1. HTTP.REQ.HEADER("User-Agent").contains("CitrixReceiver").NOT && HTTP.REQ.HEADER("Referer").EXISTS.NOT


3. HTTP.REQ.HEADER("User-Agent").contains("CitrixReceiver")


Is there a policy expression that will differentiate Plug-in traffic from web?



Link to comment
Share on other sites

These are the headers in 13.1 (or we can dig up the 13.0 header list in the citrix gateway admin guide):  https://docs.citrix.com/en-us/citrix-gateway/current-release/storefront-integration/ng-clg-session-policies-overview-con.html  (OH, irony of ironies the gateway docs are STILL referencing CLASSIC expressions instead of ADVANCED engine; there *might* be an issue with case-sensitive vs non-case-sensitive comparisons, but it is unlikely. I'll just note it below.)


But also, the vpn client and two factor is different and *might* not be able to use custom login schemas but just need regular ldap/radius integration (though hopefully someone else will weigh in if that is a problem...I'll admit I'm not sure on that.)  This article covers some of the differences in browser vs. native clients like the vpn client:  https://support.citrix.com/article/CTX223386.  I don't know if its been superseded by newer information.  So again, hopefully a few others will see this and weigh in.


To help everyone out though, please clarify the exact scenario you are trying to design: which client gets which authentication requirements and the nfactor broad strokes you are attempting.

I can't actually tell what the results you want to achieve are.

  • You want web clients to do which flow?
  • And you want the vpn client to do what instead?  And what is happening instead.


Regarding case-sensitive comparison in advanced engine.

The gateway client is usually identified with this classic expression:  REQ.HTTP.HEADER User-Agent NOTCONTAINS CitrixReceiver && REQ.HTTP.HEADER Referer NOTEXISTS

And you changed it to the advanced expression:  http.req.header("user-agent").contains("CitrixReceiver").not && http.req.header("Referer").exists.not

The logic is correct BUT remember contains in the classic expression is NOT case-sensitive, but contains in the ADVANCED engine IS CASE-SENSITIVE unless it is made non-case sensitive.  

If the clients always insert the exact header value and you are looking for the same value and there's no chance the client vs. your comparison are mixed case from each other, the case comparison won't matter.  If the header is "CitrixReceiver" and you are searching "citrixreceiver" than the comparison does matter.


Assuming, that has nothing to do with the issue and the CTX223386 doesn't help.

Test 1:

During test, what you might want to try is create a vpn1 that is only for native vpn clients and see if a vanilla ldap/radius (duo) setup works if there aren't any complicated schemas beyond the basic authe factor1 and next_factor to authe factor 2 policy.  You do want to make sure you are in fact completing both required authentications and not a cascade.

Test 2:

If this doesn't work, then you might try a classic engine vpn vserver primary policy / secondary policy and see if that works.


If Test2 works, then it is something with the nfactor parsing affecting the gateway.

If Test1 works (and you do in facto confirm it is doing BOTH and not an OR condition), then the gateway + aaa with scenario does work for the vpn and that does bring us back to one gateway trying to do the native vs. web clients.  And it still might be solvable with polcy expressions or its related to info in CTX223386.


Once we know if the vpn scenario works, then your back to figuring out how to do both together to meet your original requirements.



And if anyone else has more experience they may have much better ideas than I do on this one.



  • Like 1
Link to comment
Share on other sites

The goal is to have user sessions launched from a browser to authenticate to RADIUS(1) configured for Duo’s iFrame.

User sessions launched from the Plug-in (from Windows system tray) to authenticate to RADIUS(2) configured for Duo’s auto-push and NOT the iFrame.


Either one of these use cases test good when tested independently, however no policy expression syntax used thus far has been able to differentiate the client method accommodating the two use cases simultaneously.

Link to comment
Share on other sites

You might need to share your nfactor config to see if it is something else.

So we can see if there is an issue in the next_factor/policy bindings or the schemas.


What if you do the web client filter first and make the gateway client be "true" at a lower priority for everything else?


This forum found changing from the rfwebui to the x1 theme fixed an issue:  https://discussions.citrix.com/topic/410127-multi-factor-authentication-for-citrix-not-working/


But I don't know what would fix it aside from separate vpns.

  • Like 1
Link to comment
Share on other sites

After looking at Fiddler captures for the web (Chrome) and Plugin use-cases I noted some differentiating User-Agent Headers and requested URLs; however none of these criteria evaluated as true when connecting from the Plugin:


  1. HTTP.REQ.HEADER("User-Agent").CONTAINS("plugin") ||
  2. HTTP.REQ.HEADER("User-Agent").CONTAINS("AGEE") ||
  3. HTTP.REQ.HEADER("User-Agent").CONTAINS("NAC") ||
  4. HTTP.REQ.URL.CONTAINS("/vpn/index.html")

These expressions evaluated as true for BOTH use-cases and could not be used to handle authentication differently

  1. HTTP.REQ.HEADER("User-Agent").CONTAINS("Mozilla") ||
  2. HTTP.REQ.URL.CONTAINS("/logon/LogonPoint/").NOT
Link to comment
Share on other sites

I had a student confirm for me once in class that the workspace app sometimes presents itself as a "web client" vs the "full client" header in some scenarios. It would be nice if they had a third header that confirmed "no this is really the full client all the time for this other scenarios."


I think the vpn client problem  is just that it can't deal with certain custom schemas that requires the "web" to handle.


You might need to allow full vpn clients on vpn vserver 1 vs web access from a vpn 2.  Or open a case with support to see if there is a different way to solve this.

Link to comment
Share on other sites

The correct user-agent header for workspace app (1809 and higher, as there comes the browser engine with for nfactor) is called CWAWEBVIEW, for example:




I've done a research about the latest user-agent headers and listed these in a blogpost, as the documentation from citrix is bad in my opinion. Hope this helps https://citrixguyblog.com/2021/05/28/citrix-adc-nfactor-user-certificate-authentication-or-the-demystifying-of-user-agent-header/ 


Best Regards


  • Like 2
Link to comment
Share on other sites



Thank you for that blog post. It gives me hope that I may be able to distinguish client requests initiate from Gateway Plugin.


In you post you noted this header with "NAC/1.0" being the key criteria

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; AGEE 8.0;) NAC/1.0 plugin


However in my fiddler testing from the client I do see similar,

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; AGEE 8.0;) NAC/1.0 plugin


however fails to match on "NAC" keyword



In fact, other than the keyword "Mozilla" at the beginning, nothing else seems to be evaluated.


Is it possible there is other syntax that evaluates the entire User-agent string and not just the first word?



Link to comment
Share on other sites

  • 3 weeks later...

Sorry for the late reply, Kevin. I did some tests and it looks like the Header is hitting at the ADC-Side, but the gateway plugin isn't acting like it should. The plugin is ignoring the auth policy and throwing some random errors?! The gateway plugin always seemed a bit special to me. I think it's time for a support case, to get deeper into the correct behaviour of the plugin with the engineering team.

Link to comment
Share on other sites

  • 6 months later...

We had a similar need and we're showing some really promising results with the following expression:


I used this expression to target the session policy and in nFactor EPA scan. Initial tests seemed really promising. ?

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...