in Security

n-Factor: Clearing up the mystery


n-Factor, released in 11.0, not yet really understood and used – let’s change that! So much power and flexibility hidden in this feature. This is the first in a series of articles – and i don’t know how many it will end up, so let’s call it this first one 1/n*article – just for the fun it and staying true to n-Factor 🙂


Why is it soo bloody complicated?

Yes, 42 is a good approach here. Although i think there is the best intention behind this feature, i don’t think it has won admins heart just yet, and one of the big hurdles that it’s just a bit complicated and you may quickly lose overview. I’ll give my view on why it is, and hopefully give some tips on how to proceed.


Not like the other features.

Working with NetScaler, we are used to have a policy that defines WHEN something happens, which points WHAT and then stop. The WHEN defines a policy in a certain condition, this could be multiple conditions but usually it is very easy to grasp when you want WHAT to happen.

WHAT is an action, this is also usually a single action, that gets fired off straight away. There are profiles, which could be a combination of a lot of parameters (small actions if you may), all of theme nicely formatted in the GUI.


So, what happens in nFactor?

You’ll end up working with the following:

  • Policy
  • Policy Actions
  • Bindpoints
  • Policylabel
  • LoginSchema

Advanced use cases (not part of this article):

  • XML
  • HTML
  • Javscript


You still define a policy (WHEN) like you are used to, but the WHAT is a bit tricky, because you also control the user output(loginschema), so it’s not only sending the WHEN to an specific action like we are used to, but actually starting up a process flow(policylabel) where even more WHEN’s are defined.

Examples…. They are coming!

Sometimes, you mere also just want steer the user to another output, or want to validate some input from the user or 3rd party(could be ldap group check) and after validation process present them with some output depending on that check. (The power of NO_AUTHN and INT_LSCHEMA)

And to top it off, you have to use policylabels to invoke which loginschema to active. And the policylabel also has a number of policy bound to it.



Policy is when (expect for HTTP.REQ.URL.EQ is HTTP.REQ.COOKIE.VALUE(“NSC_TASS”).EQ – for some reason) you want something to happen, and you can control the output or the internal processing, or both.

A policy may invoke a policylabel, but it does not have to. <- wait what? Yes, depending on how you bind a policy you can select which policylabel to active, thatthen controls the loginschema.

PolicyActions are just like you are used to work with LDAP Actions, Radius Servers, SAML Profile and so on. There is one super function hidden here, which is called NO_AUTHN, more on that later.

Bindpoints are important because this is where you control which policylabel you want to invoke next.

Policylabel always have a loginschema associated to it, and 1 or more policies bound on it, and on that bindpoint it can refer to new policylabel.

Loginshemas has 2 functions.

  • To present the user with some output
  • To process some input from the user.


The output shown to the user is in the xml files, NetScaler does internal processing on the xml files, which in the end turns up as HTML in the browser. See this as a magic process you can more or less hook into if you read enough articles combined with trial and error (i spent close to 4 hours to make a like appear in a loginschema)

Process input(INT_LSHCHEMA):

When selecting INT_LSCHEMA as the schema, no output is presented to the user, so this a step where you validate data received from the user or 3rd party, and what’s different from the classic way of doing things, is that this is necessarily not the end of the login process, it’s a step into the overall validation. So you could group membership extraction after receiving the username as an input, and then if user: HansGrubers member of group “netscaler_2fa” direct him to another loginschema that will present him for 2 password fields.

LoginSchemas can be bound to a policylabel or default to the AAAVS.

READ THIS: When altering the loginschema, you can to “re-select” it for netscaler to load the new loginschema into memory

ALSO READ THIS: If you don’t see the changes take effect right away, clear your browser cache, sometimes the magic does not happen right away.



Always return success! This is what projectmanagers dream of, so let’s keep this one a technical secret for now 😉

An very important part of this nFactor, is the ability to steer users into the right flow, and having the option to just “taste” on metadata, like source ip, start url, group membership, time of day, geographical location, internal variable, and so on. However it also introduces “delay” in the authentication process, for example, if you check if user is a member of “netscaler_2fa” group, then the next view is 2 password fields, the policies on that policylabel should be NO_AUTHN which invokes an policylabel that has INT_LSCHEMA bound that then fetches the password’s and checks them against the right servers.

If you have a very long flow of authentication, you can quickly end up in a long traverse of policylabels which adds to the complexity due to the lack of overview.


Where to configure what? / how to approch it?

Drop the default login schema that you can bind on a AAAVS, it only adds to the confusing that you have something default. You can achieve the exact same thing by using a few more policies and policylabels, which in the end will force you to work with the flow that you’ll use later on if you have many factors. This is my personal opinion, but it was a big relief for me when i first understood that i didn’t have to use the login schemabinding in the AAAVS. When only using loginschema from one reference point (policylabels) you decrease the complexity of understanding on how things relate to each other.


Do proper naming! I name like the following


“int” means that i am not presenting anything to the user, but just doing internal processing of some input already giving.

“out” is the opposite, here i am presenting something for the user.

Good naming helps ALOT in n-Factor, like really a tremendously amount, when you have long complex authentication flows, it’s nice to be helped a little by the naming.

Keep the number of loginschemas to a minimum, you could easily end up with a loginschema pr configuration, but that’s really something that’s bound to explode at some point.


What’s lacking?

Properly a lot of things 🙂

Control the output in the case of a failed event. Right now you can enable “enhanced authentication feedback” (, which give users a bit more understanding on why certain things a failing, but if i wanted to add a link (for example to a helpdesk function), i would have to hack some more.

Restart the login process; when you first inside the “forest” you can’t really get out again (you need to reset the cookies). Therefore it’s a very good idea to validate the user input before sending them further into the authentication flow, when first accepted – it cannot be changed (to my understanding)

Better overview, this is a big one, and if it was solved, i’m sure many would start to pick it up. Right now there is many moving parts, and having a clear crips GUI would help to get better overview.

Clean up of what you can actually match on in a policy, like you can configure HTTP.REQ.URL, but it has no effect. And i am sure there are other examples if you really went into it. Just remove the options that are not supported, or better yet, support them 🙂

Documentation of the XML framework used in loginschems, are somewhat sporadic documented. There has been written a number of good support articles about the subject, but i am yet to see a structured documentation on what options you have available in the xml files, and specifically how those options relate to the output on the user screen (there is a whole javascript section that’s just a big puddle of reverse engineering right now)

Populate custom links with user specific data that could help a form on another website to consume ?username=hans_gruber from the url. It could perhaps also be an encrypted message that contained the reason why the user was denied access.


Further reading:


Upcoming topics on n-Factor:

Basic authentication to a website and with NSGW

Insert custom links

Group extraction based decision making

Integrating native OTP in dual domain setup.


Questions? Leave a comment or find me on social media.

What do you think?