nFactor: Dual Factor Authentication with Selective Authentication Factors Based on Active Directory Group Membership

nFactor: Dual Factor Authentication with Selective Authentication Factors Based on Active Directory Group Membership

book

Article ID: CTX220793

calendar_today

Updated On:

Description

This article presents the starting point of some possibilities that nFactor allows. The main objective is to present the same solution using two different paths (or implementations). The end result is that depending on the user’s groups, you get either one factor authentication or dual factor authentication. Remember to always hit the LB Virtual Server first and have the NetScaler redirect you to the AAA-TM Virtual Server.

Background

With the advent of the new NetScaler 11.1 firmware, Citrix introduced a new feature to the authentication, authorization and audit (AAA) module called nFactor. nFactor provides a method to display multi-step authentication based on different types of criteria.

This article contains two examples:
  1. Ask for a Username and based on Active Directory group membership we will either prompt for two factor or single factor authentication.
  2. Present initial single factor authentication and based on group membership the second factor will be presented or the user will be allowed to proceed with single factor login.

How nFactor Works?

nFactor is quite simple to explain:

  • The evaluation begins on the authentication virtual server with an advanced authentication policy, action and a schema. This policy invokes a policy label. This policy label will be the next authentication method (factor).
  • When an authentication factor is successful the current policy label (or vserver in case of the first method) calls the NEXT policy label specified by nextFactor. Until a policy label has END as its next factor. Then authentication is considered successful.
  • In case a factor fails the authentication (action returns false) the next policy in the policy label is involved. (later articles will address the FALLBACK action.).
  • Each policy label could potentially have its own schema.

Prerequisites

This article assumes that you are familiar with nFactor, Shell commands, XML and text editors. This example describes a three possible login pages:
  1. Login page with a single field for username
  2. Login page with login field and LDAP password
  3. Login page with login field, LDAP password and Second Factor password.
In order to achieve this, the following must be at hand:
  • XML Schema. This file represents what will be shown in the page. These can be found on /flash/nsconfig/loginschema/LoginSchema/
  • Authentication Action (3 LDAP and 1 RADIUS). This represents the descriptors of the login servers, i.e. this can be a LDAP server, port, protocol and username to bind.
  • Authentication policy, one for each authentication action.
  • Authentication Virtual Server (1 Vserver)
  • NetScaler running 11.1

Instructions

Use Case 1

The fist case will be the following. Each image describes what the user will see:

User-added image

After the first login page the system will check group membership on Active Directory. If the user does not belong to the Security Group “Managers” he will be prompted for Dual Authentication. Otherwise the user is asked for the Domain credentials only.

The authentication flow from a configuration perspective is described by the following diagram:

User-added image

On the first screen the username is captured and Group Membership is evaluated, based on the user’s memberships the authentication is forked between single factor and dual factor.

Actual Configuration Case 1

Create your three authentication LDAP actions, two of them will be for Group Extraction (Authentication Disabled) and the third will perform the actual authentication.

add authentication ldapAction Auth_AD -serverIP 192.168.40.7 -ldapBase "dc=test,dc=com" -ldapBindDn daniel@test.com -ldapLoginName SAMAccountName -groupAttrName memberOf -subAttributeName CN
add authentication ldapAction Auth_AD_GroupsExtraction -serverIP 192.168.40.7 -ldapBase "dc=test,dc=com" -ldapBindDn daniel@test.com -ldapLoginName SAMAccountName -groupAttrName memberOf -subAttributeName CN -authentication DISABLED
add authentication ldapAction Auth_AD_GroupsExtraction_Only_Managers -serverIP 192.168.40.7 -authTimeout 5 -ldapBase "dc=test,dc=com" -ldapBindDn daniel@test.com -ldapLoginName SAMAccountName -searchFilter "memberOf=CN=Test,CN=Builtin,dc=test,dc=com" -groupAttrName memberOf -subAttributeName CN -authentication DISABLED
add authentication radiusAction Entrust -serverIP 192.168.40.110 -serverPort 1812 -authTimeout 10 -radKey 88a8d12eaaa58e7ae02251cf9cef1c8fb349d86c4d1 -encrypted

In bold you can see what makes each LdapAction unique. Auth_AD represents the LDAP action for authentication. The other two LDAP actions that point to the same server uses filters to select what will the group extraction action return. In the action Auth_AD_GroupsExtraction_Only_Managers the system is searching for all users that are members of the security group Managers, if the user does not belong to that group the search will return empty. This does not perform authentication hence, the two authentication actions for group extraction have authentication disabled.

The virtual server is the first object created:

add authentication vserver AAATEST SSL 192.168.40.153 443 -AuthenticationDomain test.com

nFactor makes use of advanced authentication policies, policyLabels and Schemas. In order to create the configuration the login Schemas must be created:

add authentication loginSchema username-only -authenticationSchema "/nsconfig/loginschema/nopwd.xml"
add authentication loginSchema USERNAME-PASS -authenticationSchema "/nsconfig/loginschema/passwd1.xml" -SSOCredentials YES
add authentication loginSchema 2FA -authenticationSchema "/nsconfig/loginschema/passwd2.xml” -SSOCredentials YES
add authentication loginSchema NOSCHEMA -authenticationSchema noschema
add authentication loginSchemaPolicy SCHEMA_POLICY_NOPWD -rule true -action username-only

In the commands above, the parameter -authenticationSchema points to the XML file used, the files can be found at the end of this document. Also the SSOCredentials set YES for loginSchemas that have LDAP factors bound to them is usually ideal.

Note 1: The schema NOSCHEMA tells the NetScaler not to go back for more information.
Note 2: The loginSchemaPolicy is required in order to bind on the virtual server and present the initial web page.

bind authentication vserver AAATEST -policy SCHEMA_POLICY_NOPWD -priority 100 -gotoPriorityExpression END

Create the policy Labels that will be next factors:

add authentication policylabel User_pass -loginSchema USERNAME-PASS
add authentication policylabel User_radius_ldap -loginSchema 2FA
add authentication policylabel User_ldap -loginSchema USERNAME-PASS

Create and bind the advance policies that will start the process.

add authentication Policy Group_Extract -rule true -action Auth_AD_GroupsExtraction
add authentication Policy Group_Extract_Member_is_Manager -rule true -action Auth_AD_GroupsExtraction_Only_Managers
bind authentication vserver AAATEST -policy Group_Extract_Member_is_Manager -priority 90 -nextFactor User_ldap
bind authentication vserver AAATEST -policy Group_Extract -priority 100 -nextFactor User_radius_ldap

Note: In this example both bound policies are doing group extraction, but usually this is not the case. The usual case would be that Group_Extract policy does not perform group extraction since by default users will be prompted with dual factor authentication, so a NOAUTH action can be used. The downside to this is that in the next factor there will be no groups populated. So Group_Extraction is doing group extraction and LDAP action to enhance the example.

Create and bind the policies used inside each factor:

add authentication Policy User-ldap -rule TRUE -action Auth_AD
add authentication Policy Username-ldap -rule TRUE -action Auth_AD
add authentication Policy RADIUS_ADV -rule TRUE -action Entrust_AM
bind authentication policylabel User_pass -policyName User-ldap -priority 100 -gotoPriorityExpression END
bind authentication policylabel user_ldap -policyName Username-ldap -priority 100 -gotoPriorityExpression END
bind authentication policylabel User_radius_ldap -policyName RADIUS_ADV -priority 100 -gotoPriorityExpression NEXT -nextFactor User_ldap

The loginSchema represents the web page and tells how many fields are displayed, but it is on each policyLabel where the authentication action is performed for each field. The factor does not represent the login page, instead in matches each field on the login page. For example a dual factor login page will have two factors.

Use Case 2

In this particular case the first login screen includes Username and LDAP Password. Depending on the group extraction of this authentication attempt a second login screen will be displayed that will ask for the authentication’s second factor.

This configuration uses only the Authentication Action for LDAP and RADIUS, group extraction is done at the same time as LDAP authentication.

The flow of this process is outlined in the following diagram:

User-added image

CHECK_GRPS will perform evaluation on group membership that was done on USer-name-pass and determine if the next factor is invoked or LDAP was enough and END the authentication.

Actual Configuration Case 2

We will use a different virtual server than the one used in Case 1 to explain the process:

add authentication vserver AAATEST2 SSL 192.168.40.155 443

From a configuration perspective, this is a three-step factor but the end user sees only two steps. The middle step is hidden from the user and is performed on the NetScaler to determine if the user belong to a certain group and prompts for the second factor.

add authentication ldapAction Auth_AD -serverIP 192.168.40.7 -ldapBase "dc=test,dc=com" -ldapBindDn daniel@test.com -ldapLoginName SAMAccountName -groupAttrName memberOf -subAttributeName CN
add authentication radiusAction Entrust -serverIP 192.168.40.110 -serverPort 1812 -authTimeout 10 -radKey 88a8d12eaaa58e7ae02251cf9cef1c8fb349d86c4d1 –encrypted
add authentication Policy User-name-pass -rule TRUE -action Auth_AD
add authentication Policy IS_MANAGER_POL -rule "http.REQ.USER.IS_MEMBER_OF(\"Test\")" -action NO_AUTHN
add authentication Policy RADIUS_NON_MANAGER -rule true -action NOAUTH
add authentication Policy RADIUS_ADV –rule true –action Entrust_AM

The above rules are the necessary configurations to authenticate the users, via single or dual factor. The Policy IS_MANAGER_POL will check in the middle factor if the user can by-pass the second factor.

Authentication starts on the Virtual Server with the following configurations.

add authentication loginSchema USERNAME-PASS-authenticationSchema "/nsconfig/loginschema/passwd1.xml" -SSOCredentials YES
add authentication loginSchemaPolicy LS_POL_USER_PASS -rule true -action USERNAME-PASS
bind authentication vserver AAATEST2 -policy LS_POL_USER_PASS -priority 100 -gotoPriorityExpression END

The above configuration tells the NetScaler to present to the user LoginSchema passwd1.xml and apply factor User-name-pass with next END (temporary) that will be changed later to factor CHECK_GRPS. If the user successfully authenticates the next factor is performed and Group Extraction would have been performed.

add authentication policylabel CHECK_GRPS -loginSchema NOSCHEMA
add authentication policylabel user_radius_non_manager -loginSchema username-PASS
bind authentication policylabel CHECK_GRPS -policyName IS_MANAGER_POL -priority 100 -gotoPriorityExpression END
bind authentication policylabel CHECK_GRPS -policyName RADIUS_NON_MANAGER -priority 110 -gotoPriorityExpression NEXT -nextFactor user_radius_non_manager

The factor invoked by policyLabel CHECK_GRPS is hidden from the user and happens within the NetScaler, the following above configuration lines create the factor and bindings.

The factor is hidden from the user and all happens inside the NetScaler, this can be verified with LoginSchema NOSCHEMA. This factor does the group extraction check with policy IS_MANAGER_POL, if the user does not belong to the appropriate group then the next policy in the policyLabel is RADIUS_NON_MANAGER that will execute the next factor user_radius_non_manager. IS_MANAGER_POL is particular because it has the Action NOAUTH, if executed will always return Action true, and will invoke the END.

Once the second factor is invoked the following configurations will make the second factor appear.

bind authentication policylabel user_radius_non_manager -policyName RADIUS_ADV -priority 100 -gotoPriorityExpression END
bind authentication vserver AAATEST2 -policy User-name-pass -priority 100 -nextFactor CHECK_GRPS -gotoPriorityExpression NEXT

The user will see a single password field and the authentication action will be sent to the Radius server for final authentication invoking the END if the Radius server return Accept.

Nopwd.xml
<?xml version="1.0" encoding="utf-8"?>
<AuthenticateResponse xmlns="http://citrix.com/authentication/response/1">
<Status>success</Status>
<Result>more-info</Result>
<StateContext/>
<AuthenticationRequirements>
<PostBack>/nf/auth/doAuthentication.do</PostBack>
<CancelPostBack>/Citrix/Authentication/ExplicitForms/CancelAuthenticate</CancelPostBack>
<CancelButtonText>Cancel</CancelButtonText>
<Requirements>
<Requirement>
<Credential>
<ID>login</ID>
<SaveID>ExplicitForms-Username</SaveID>
<Type>username</Type>
</Credential>
<Label>
<Text>User name</Text>
<Type>plain</Type>
</Label>
<Input>
<AssistiveText>Please supply either username as
saamaccountname</AssistiveText>
<Text>
<Secret>false</Secret>
<ReadOnly>false</ReadOnly>
<InitialValue/>
<Constraint>.+</Constraint>
</Text>
</Input>
</Requirement>
<Requirement>
<Credential>
<Type>none</Type>
</Credential>
<Label>
<Text> Please submit credentials to continue Login ...</Text>
<Type>confirmation</Type>
</Label>
<Input/>
</Requirement>
<Requirement>
<Credential>
<ID>saveCredentials</ID>
<Type>savecredentials</Type>
</Credential>
<Label>
<Text>Remember my password</Text>
<Type>plain</Type>
</Label>
<Input>
<CheckBox>
<InitialValue>false</InitialValue>
</CheckBox>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>loginBtn</ID>
<Type>none</Type>
</Credential>
<Label>
<Type>none</Type>
</Label>
<Input>
<Button>Log On</Button>
</Input>
</Requirement>
</Requirements>
</AuthenticationRequirements>
</AuthenticateResponse>

passwd1.xml
<?xml version="1.0" encoding="utf-8"?>
<AuthenticateResponse xmlns="http://citrix.com/authentication/response/1">
<Status>success</Status>
<Result>more-info</Result>
<StateContext/>
<AuthenticationRequirements>
<PostBack>/nf/auth/doAuthentication.do</PostBack>
<CancelPostBack>/Citrix/Authentication/ExplicitForms/CancelAuthenticate</CancelPostBack>
<CancelButtonText>Cancel</CancelButtonText>
<Requirements>
<Requirement>
<Credential>
<ID>login</ID>
<SaveID>ExplicitForms-Username</SaveID>
<Type>username</Type>
</Credential>
<Label>
<Text>User name</Text>
<Type>plain</Type>
</Label>
<Input>
<AssistiveText>Please supply either domain\username or user@fully.qualified.domain</AssistiveText>
<Text>
<Secret>false</Secret>
<ReadOnly>false</ReadOnly>
<InitialValue>${http.req.user.name}</InitialValue>
<Constraint>.+</Constraint>
</Text>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>passwd</ID>
<SaveID>ExplicitForms-Password</SaveID>
<Type>password</Type>
</Credential>
<Label>
<Text>Password:</Text>
<Type>plain</Type>
</Label>
<Input>
<Text>
<Secret>true</Secret>
<ReadOnly>false</ReadOnly>
<InitialValue/>
<Constraint>.+</Constraint>
</Text>
</Input>
</Requirement>
<Requirement>
<Credential>
<Type>none</Type>
</Credential>
<Label>
<Text>Second factor</Text>
<Type>confirmation</Type>
</Label>
<Input/>
</Requirement>
<Requirement>
<Credential>
<ID>saveCredentials</ID>
<Type>savecredentials</Type>
</Credential>
<Label>
<Text>Remember my password</Text>
<Type>plain</Type>
</Label>
<Input>
<CheckBox>
<InitialValue>false</InitialValue>
</CheckBox>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>loginBtn</ID>
<Type>none</Type>
</Credential>
<Label>
<Type>none</Type>
</Label>
<Input>
<Button>Log On</Button>
</Input>
</Requirement>
</Requirements>
</AuthenticationRequirements>
</AuthenticateResponse>

passwd2.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<AuthenticateResponse xmlns="http://citrix.com/authentication/response/1">
<Status>success</Status>
<Result>more-info</Result>
<AuthenticationRequirements>
<PostBack>/nf/auth/doAuthentication.do</PostBack>
<CancelPostBack>/p/u/doLogoff.do</CancelPostBack>
<CancelButtonText>Cancel</CancelButtonText>
<Requirements>
<Requirement>
<Credential>
<Type>none</Type>
</Credential>
<Label>
<Text>Please log on</Text>
<Type>heading</Type>
</Label>
<Input/>
</Requirement>
<Requirement>
<Credential>
<ID>login</ID>
<SaveID>login</SaveID>
<Type>username</Type>
</Credential>
<Label>
<Text>User name:</Text>
<Type>plain</Type>
</Label>
<Input>
<Text>
<ReadOnly>false</ReadOnly>
<InitialValue/>
<Constraint>.+</Constraint>
</Text>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>passwd</ID>
<SaveID>passwd</SaveID>
<Type>password</Type>
</Credential>
<Label>
<Text>Password:</Text>
<Type>plain</Type>
</Label>
<Input>
<Text>
<Secret>true</Secret>
<Constraint>.+</Constraint>
</Text>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>passwd1</ID>
<SaveID>passwd1</SaveID>
<Type>password</Type>
</Credential>
<Label>
<Text>Passcode:</Text>
<Type>plain</Type>
</Label>
<Input>
<Text>
<Secret>true</Secret>
<Constraint>.+</Constraint>
</Text>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>savecredentials</ID>
<SaveID/>
<Type>savecredentials</Type>
</Credential>
<Label>
<Text>Remember my credentials</Text>
<Type>plain</Type>
</Label>
<Input>
<AssistiveText/>
<CheckBox>
<InitialValue>false</InitialValue>
</CheckBox>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>Logon</ID>
<Type>none</Type>
</Credential>
<Label>
<Type>none</Type>
</Label>
<Input>
<Button>Submit</Button>
</Input>
</Requirement>
</Requirements>
</AuthenticationRequirements>
</AuthenticateResponse>

Issue/Introduction

nFactor: Dual Factor Authentication with Selective Authentication Factors Based on Active Directory Group Membership

Additional Information

For NO Auth : https://support.citrix.com/article/CTX222713
Entrust_AM is the name of Action type which is configured under Radius setting. Still for more information below :
https://en.wikipedia.org/wiki/Entrust