Overview

Citrix Consulting engaged in a project that involved integrating the NetScaler platform with a third party multifactor authentication solution, Anakam.TFA.  This blog article has been presented with the aim to disseminate knowledge that has been acquired from the field.  It attempts to demonstrate the real world applications of the NetScaler platform and how to integrate with other industry solutions.

The following outlines the issue that the featured integration attempts to reconcile.

  1. End-user authenticates with LDAP credentials for 1st factor.
  2. End-user is sent a passcode for 2nd factor.
  3. End-user’s device is registered for a predetermined duration, for which subsequent authentication attempts will not require a 2nd factor authentication challenge.  However, 1st factor will always be required.

When an end-user successfully authenticates, their device is registered within the Anakam.TFA server.  The duration for device registration is also configurable within the Anakam.TFA management interface.  The Anakam.TFA software allows for the discontinuation of a 2nd factor authentication if the end-user’s device is registered in the system and is within the device registration duration limits.  This blog will not focus on how to configure the relevant settings within the Anakam.TFA software; instead, this blog article will focus on how to utilize the NetScaler to communicate with the Anakam.TFA server using HTTP callouts, Anakam.TFA’s REST APIs, and JavaScript.

REST APIs

This solution requires the use of REST APIs for customized communication with the Anakam.TFA server.  Therefore, it is important to first understand how to utilize the APIs in order to communicate with the Anakam.TFA server without incorporating the NetScaler (NetScaler).  This will provide a benchmark for comparison when the time comes to incorporate the NetScaler.  One tool that can be utilized is Google Chrome’s Advanced REST Client.  This tool can be downloaded from Google Chrome’s App store.  This tool can be used to send the relevant POST and PUT HTTP requests to the Anakam.TFA server for API communication.  Used correctly, this tool will help validate the correct sequence of API requests in order to successfully complete the various authentication processes.

API Sequence

The following will depict the correct sequence of requests and their expected responses in order to successfully authenticate an end-user’s device that has not yet been registered with the Anakam.TFA server.

  1. Acquire the authentication key.

Request:

POST http://10.1.1.10:8080/tfa/api/5.5/default/auth?applicationKey=/&amp;userKey=<em>UserName</em>

Response:
&lt;AuthenticationToken&gt;&lt;DomainKey&gt;default&lt;/DomainKey&gt;&lt;UserKey&gt;aah022&lt;/UserKey&gt;
&lt;AuthenticationKey&gt;11f16e1c-ed81-4e22-8018-e4cf70027375&lt;/AuthenticationKey&gt;
&lt;ApplicationKey&gt;/&lt;/ApplicationKey&gt;
&lt;ProfileKey&gt;1&lt;/ProfileKey&gt;
&lt;TargetUrl&gt;/tfademo/default/success.jsp&lt;/TargetUrl&gt;
&lt;Status&gt;TOKEN_CREATED&lt;/Status&gt;
&lt;CreatedDate&gt;2014-08-01T00:13:51.078-04:00&lt;/CreatedDate&gt;
&lt;/AuthenticationToken&gt;

  1. Execute the command to receive the 2nd factor passcode via email communication.

Request:

PUT http://10.11.252.114:8080/tfa/api/5.5/default/challenge/11f16e1c-ed81-4e22-8018-e4cf70027375
&lt;request command="execute"&gt;
&lt;parameters&gt;
&lt;parameter value="10.0.0.4" name="remoteIpAddress" /&gt;
&lt;parameter value="methods.email~Primary" name="destination.selection" /&gt;
&lt;parameter value="11f16e1c-ed81-4e22-8018-e4cf70027375" name="authenticationKey" /&gt;
&lt;/parameters&gt;
&lt;/request&gt;

Response:
&lt;response status="parameters_accepted" step="delivery"&gt;
&lt;parameters&gt;
&lt;parameter type="text" value="11f16e1c-ed81-4e22-8018-e4cf70027375" name="authenticationKey"/&gt;
&lt;/parameters&gt;
&lt;/response&gt;

  1. Advance the authentication process to the next step by sending the API command “get-params”.  This API command moves the authentication logic to the next step.  The API documentation provides further details.  Without this command being executed, the passcode will not be generated and delivered to the end-user.

Request:

&lt;request command="get-params"&gt;
&lt;parameters&gt;
&lt;parameter name="remoteIpAddress" value="10.0.0.4" /&gt;
&lt;parameter value="Chrome/35.0.1916.153" name="userAgent" /&gt;
&lt;parameter name="authenticationKey" value="11f16e1c-ed81-4e22-8018-e4cf70027375" /&gt;
&lt;/parameters&gt;
&lt;/request&gt;

Response:
&lt;response status="parameters_required" step="challenge"&gt;
&lt;parameters&gt;
&lt;parameter type="action" name="select-method"/&gt;
&lt;parameter type="text" name="user.passcode"/&gt;
&lt;parameter type="boolean" name="user.register.device"/&gt;
&lt;parameter type="single_option" name="user.register.device.duration"&gt;
&lt;options&gt;
&lt;option value="8"/&gt;
&lt;/options&gt;
&lt;/parameter&gt;
&lt;parameter type="text" value="11f16e1c-ed81-4e22-8018-e4cf70027375" name="authenticationKey"/&gt;
&lt;/parameters&gt;
&lt;messages&gt;
&lt;message key="passcode.sent.to.email"&gt;&lt;value&gt;aXXX@citrix.com&lt;/value&gt;
&lt;/message&gt;
&lt;/messages&gt;
&lt;/response&gt;

  1. Enter the passcode that was sent to the email for 2nd factor authentication.  In addition, the duration for device registration is hardcoded to be enabled for every user for a period of 8 hours.  These values are configurable but are hardcoded within this particular use-case.

Request:

&lt;request command="execute"&gt;
&lt;parameters&gt;
&lt;parameter name="remoteIpAddress" value="10.0.0.4" /&gt;
&lt;parameter value="Chrome/35.0.1916.153" name="userAgent" /&gt;
&lt;parameter name="user.passcode" value="56211" /&gt;
&lt;parameter value="true" name="user.register.device" /&gt;
&lt;parameter value="8" name=" user.register.device.duration " /&gt;
&lt;parameter name="authenticationKey" type="text" value="11f16e1c-ed81-4e22-8018-e4cf70027375" /&gt;
&lt;/parameters&gt;
&lt;/request&gt;

Response:
&lt;response status="authenticated" step="challenge"&gt;
&lt;parameters&gt;
&lt;parameter type="text" value="2bc84ac2-d278-43f4-8cef-2f6d946efe8b" name="deviceKey" /&gt;
&lt;parameter type="text" value="11f16e1c-ed81-4e22-8018-e4cf70027375" name="authenticationKey" /&gt;
&lt;/parameters&gt;
&lt;messages&gt;
&lt;message key="passcode.sent.to.email"&gt;
&lt;value&gt;aXXX@citrix.com&lt;/value&gt;
&lt;/message&gt;
&lt;/messages&gt;
&lt;/response&gt;

 

The authentication process for an unregistered device is now complete.  The following depicts the correct sequence of steps for the authentication process of end-users that have registered devices.

  1. Acquire the authentication key.

Request:

POST http://10.1.1.10:8080/tfa/api/5.5/default/auth?applicationKey=/&amp;userKey=<em>UserName</em>

Response:
&lt;AuthenticationToken&gt;
&lt;DomainKey&gt;default&lt;/DomainKey&gt;
&lt;UserKey&gt;aah022&lt;/UserKey&gt;
&lt;AuthenticationKey&gt;5986ed01-b3f5-4294-aa6b-558dba0bb3d4&lt;/AuthenticationKey&gt;
&lt;ApplicationKey&gt;/&lt;/ApplicationKey&gt;
&lt;ProfileKey&gt;1&lt;/ProfileKey&gt;
&lt;TargetUrl&gt;/tfademo/default/success.jsp&lt;/TargetUrl&gt;
&lt;Status&gt;TOKEN_CREATED&lt;/Status&gt;
&lt;CreatedDate&gt;2014-08-01T00:13:51.078-04:00&lt;/CreatedDate&gt;
&lt;/AuthenticationToken&gt;

  1. Send a request to the server containing the device key that was acquired from the first successful authentication and the authentication key that was recently acquired in step 1.

Request:

PUT http://10.11.252.114:8080/tfa/api/5.5/default/challenge/5986ed01-b3f5-4294-aa6b-558dba0bb3d4
&lt;request command="execute"&gt;
&lt;parameters&gt;
&lt;parameter value="10.0.0.4" name="remoteIpAddress" /&gt;
&lt;parameter value="5986ed01-b3f5-4294-aa6b-558dba0bb3d4" name="authenticationKey" /&gt;
&lt;parameter value="2bc84ac2-d278-43f4-8cef-2f6d946efe8b" name="deviceKey" /&gt;
&lt;/parameters&gt;
&lt;/request&gt;

Response:
&lt;response status="authenticated" step="terminated"&gt;
&lt;parameters&gt;
&lt;parameter type="text" value="5986ed01-b3f5-4294-aa6b-558dba0bb3d4" name="authenticationKey" /&gt;
&lt;/parameters&gt;
&lt;/response&gt;

The authentication process for registered devices is now complete.  Having this output is important for the next phase of incorporating this logic on the NetScaler.  It will provide a guideline that we will follow to allow for both the scenarios of authenticating with a registered device versus an unregistered device.

NetScaler Configuration

Unregistered Device Authentication

The configuration that will be required to implement the solution on the NetScaler will incorporate responder policies, http callouts, and JavaScript to compartmentalize and drive the customized authentication process.  At a high-level, JavaScript is used to control how HTTP requests are delivered to the NetScaler from the client’s browser and responder policies are configured to trigger on specific HTTP requests which subsequently trigger responder actions.  Responder actions invoke HTTP callouts which are also REST API requests that are sent to the Anakam.TFA server.  In addition, Responder actions deliver JavaScript that instructs the client’s browser how to formulate the appropriate HTTP request in order to drill down the customized authentication process.  The following presents the details of how this is implemented on the NetScaler.

  1. End-user logs in to the NetScaler Gateway logon page.  A responder policy is configured to capture the username and then use that information for the authentication request to the Anakam.TFA server for the second factor authentication.  In order to do this, the first thing that needs to be done is to modify the “index.html” file and change the Form action from “/cgi/login” to another distinct destination in order to trigger the relevant responder policy.  This is necessary because a responder policy will not trigger if the expression is configured to trigger on the URL of “/cgi/login”.  This is by design.  Therefore we modify this file in order to be able to capture the user’s credentials during a logon attempt.  The index.html page is found on the NetScaler’s hard drive within the following location:  /var/netscaler/gui/vpn
Index.html
Index.html snippet

Responder Policy:

This policy triggers due to the index.html file modification as can be seen in the above screenshot.

Responder Policy
Responder Policy Screenshot

Responder Action:

This responder action is configured to invoke an HTTP callout that initiates the 2nd factor authentication process.  The Anakam.TFA server responds with an authentication key that pertains to the particular user that is attempting to authenticate.  This authentication key is used to track the authentication process for a particular user.  The HTTP callout returns the authentication key as text, and then the responder action is configured to set the authentication key as a cookie so that it can be utilized accordingly throughout the authentication process.  The cookie for the authentication key is called “AuthKey”.  The name is arbitrary and can be given any other name that is acceptable to the organization.  In addition, this responder action utilizes JavaScript to instruct the end-user’s client web browser to perform the following functions:

  1. Instantiates a function that acquires the value of a cookie based on the cookie name
  2. An “If..Else” statement that determines if a Device Key cookie exists within the client’s web browser.  Based upon the result, the client’s web browser will initiate a HTTP request that will perform authentication based on a device key’s existence.  This section describes the authentication process with no device key.  The next section will focus on the authentication process with the device key.


"HTTP/1.1 200 OK\r\nSet-Cookie: AuthKey="+SYS.HTTP_CALLOUT(ana_logon)+"; Path=/\r\nSet-Cookie: User="+HTTP.REQ.BODY(200).TYPECAST_NVLIST_T('=','&amp;').VALUE("login")+";Path=/\r\nSet-Cookie: Password="+HTTP.REQ.BODY(200).TYPECAST_NVLIST_T('=','&amp;').VALUE("passwd")+";Path=/\r\nConnection: close\r\n\r\n
&lt;script&gt;
function ns_getcookie(name)
{
 var cookie=document.cookie;
 if(cookie.length &gt; 0) {
 begin=cookie.indexOf(name+\"=\");"+"
 if(begin!=-1) {
 begin+=name.length+1;
 end=cookie.indexOf(\";\", begin);
 if(end==-1) end=cookie.length;
 return decodeURIComponent(cookie.substring(begin, end));;"+"
 }
 }
 return null;
}
window.onload=function() {"+"
if (ns_getcookie(\"DeviceKey\")==null) {window.location = \"/vpn/anakam/ex_set_challenge\"; } else {window.location = \"/vpn/anakam/DeviceKey_Authentication\";}"+"
}
&lt;/script&gt;"


HTTP Callout: This HTTP callout sends the first request required to initiate the authentication process using the appropriate REST API calls. Each request sent to the Anakam.TFA server requires an HTTP header called “Authorization”.  This header contains credentials required by the Anakam.TFA server to use the REST APIs.  It is Base64 encoded.

  1. The second step within this customized authentication process is to instruct the Anakam.TFA server on how to deliver the passcode that is to be utilized for the 2nd factor authentication.  Examples include SMS or Email.  However, there are other methods that the Anakam.TFA server supports.  Within this particular use-case, email is being used.

Responder Policy: This is the second responder policy that triggers, which also aligns with the authentication process for the Anakam.TFA server. Responder Action: This responder action invokes the HTTP callout that instructs the Ankam.TFA server on how to deliver the passcode for 2ndfactor authentication.  The HTTP callout result will return text that represents the status of the response to the request that was sent by the HTTP callout on how to send the passcode.  This result is stored as a cookie on the client’s web-browser.  This cookie is called “ParametersStatus”.  This name can be changed and is not important to the functioning of the authentication process. This responder action also contains JavaScript that instructs the client’s web browser to perform the following:

  1. Request parameters for passcode authentication from the Anakam.TFA server.  This step is mandatory for advancing the authentication process on the Anakam.TFA server.


"HTTP/1.1 200 OK\r\nSet-Cookie: ParametersStatus="+SYS.HTTP_CALLOUT(a2)+";Path=/\r\nConnection: close\r\n\r\n
&lt;script&gt;
window.onload=function() {
window.location=\"/vpn/anakam/get_params\";
}
&lt;/script&gt;"

HTTP Callout:

This HTTP callout executes a command that instructs the Anakam.TFA server on how to deliver the passcode.


"PUT /tfa/api/5.5/default/challenge/"+HTTP.REQ.COOKIE.VALUE("AuthKey")+" HTTP/1.1\r\nHost: 10.11.252.114:8080\r\nContent-Type: Application/XML\r\nConnection:"+" keep-alive\r\nContent-Length: 1000\r\nAuthorization: Basic YXBpLWFkbWluOkthbGVpZGEuMjAxNA=="+"
\r\n\r\n&lt;request command=\"execute\"&gt;"+"
&lt;parameters&gt;"+"
&lt;parameter value=\""+ Client.IP.SRC +"\" name=\"remoteIpAddress\" /&gt;"+"
&lt;parameter value=\"methods.email~Primary\" name=\"destination.selection\" /&gt;"+"
&lt;parameter value=\"" + HTTP.REQ.Cookie.Value("AuthKey") +"\" name=\"authenticationKey\" /&gt;"+"
&lt;/parameters&gt;"+"
&lt;/request&gt;"

Within this second HTTP Callout, we need to switch to expression based requests in order to utilize advance dynamic expressions to acquire data at runtime.  For example, acquiring cookie values that will be utilized as parameters that the Anakam.TFA server requires for the authentication process.

Essentially, the text above represents how the request that is sent to the Anakam.TFA server is constructed on the NetScaler.  The configuration within the NetScaler editor is either text/strings or expressions that acquire data at runtime.  The text/strings need to be within quotes, however the expressions do not.  The quotes need to be escaped with a backslash or an error will result upon saving the configuration.  In addition, if the configuration gets too long, the following symbols will shorten the string in order to stay beneath the maximum limit: “+”.  These can be placed at the end of each line as can also be seen above within the expression based request.

  • HTTP.REQ.COOKIE.VALUE(“AuthKey”)
  • Client.IP.SRC
  1. This next step is unique to the Anakam.TFA authentication process.  It is required to advance the authentication process.

Responder Policy:

This responder policy triggers in order to advance the authentication logic to the next step.

Responder Action:

This responder action invokes an HTML callout that advances the authentication process.  A status is returned as text and is set as a cookie called “GetParams”.  This name is not important for the authentication process.  This responder action also returns an HTML page to the end-user so that they can enter the passcode that was sent to them via email.


"HTTP/1.1 200 OK\r\nSet-Cookie: GetParams="+SYS.HTTP_CALLOUT(a4)+"; Path=/\r\nConnection: close\r\n\r\n"+"&lt;!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd/">http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\</a>"&gt;\n"+"&lt;html xmlns=\"<a href="http://www.w3.org/1999/xhtml/">http://www.w3.org/1999/xhtml\</a>"&gt;\n"+"&lt;HTML&gt;&lt;HEAD&gt;\n"+"&lt;TITLE&gt;Citrix Access Gateway&lt;/TITLE&gt;\n"+"&lt;link rel=\"SHORTCUT ICON\" href=\"/vpn/images/AccessGateway.ico\" type=\"image/vnd.microsoft.icon\"&gt;\n"+"&lt;META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"&gt;\n"+"&lt;script type=\"text/javascript\" src=\"/vpn/nsshare.js\"&gt;&lt;/script&gt;\n"+"&lt;script type=\"text/javascript\" src=\"/vpn/resources.js\"&gt;&lt;/script&gt;\n"+"&lt;script type=\"text/javascript\" language=\"javascript\"&gt;\n"+"var Resources = new ResourceManager(\"/vpn/resources/{lang}\", \"DIALOGUE_HTML\");\n"+"&lt;/script&gt;\n"+"&lt;style type=\"text/css\"&gt;\n"+"body\n"+"{\n"+" visibility: hidden;\n"+"}\n"+"&lt;/style&gt;\n"+"&lt;script language=\"javascript\" type=\"text/javascript\"&gt;DialogInclude();&lt;/script&gt;\n"+"&lt;/HEAD&gt;\n"+"&lt;BODY id=bodyTag onload=\"document.dlgform.response.focus()\"&gt;\n"+"&lt;script type=\"text/javascript\" language=\"javascript\"&gt;DialogueBodyI();&lt;/script&gt;\n"+"&lt;div id=\"dialogueStr\"&gt;\n"+"&lt;/div&gt;\n"+"&lt;script type=\"text/javascript\" language=\"javascript\"&gt;\n"+"DialogueBodyII();\n"+"Resources.Load();\n"+"&lt;/script&gt;\n"+"&lt;/BODY&gt;\n"+"&lt;/HTML&gt;\n"

Within the HTML body tag, JavaScript is invoked to acquire the data entered in the dialogue box and then perform a form post.  The JavaScript function is called “DialogueBodyI()”.  This function is located in a file called “nsshare.js” which located on the NetScaler hard drive in the following location:  /var/netscaler/gui/vpn.

As can be seen within the above screenshot, there is a post action that is changed from “/cgi/dlge” to “/vpn/anakam/passcode”.  This modification allows for the configuration of a responder policy that will trigger when a HTTP request traverses the NetScaler for the custom URL – “/vpn/anakam/passcode”.  As with “/cgi/login”, a responder policy will not trigger for requests to “/cgi/dlge”.  This is by design.  Therefore, we change the URL to something else to regain control.

HTTP Callout:


"PUT /tfa/api/5.5/default/challenge/"+HTTP.REQ.COOKIE.VALUE("AuthKey")+" HTTP/1.1\r\nHost: 10.11.252.114:8080\r\nContent-Type: Application/XML\r\nConnection:"+" keep-alive\r\nContent-Length: 1000\r\nAuthorization: Basic YXBpLWFkbWluOkthbGVpZGEuMjAxNA=="+"
\r\n\r\n&lt;request command=\"get-params\"&gt;"+"
&lt;parameters&gt;"+"
&lt;parameter value=\""+ Client.IP.SRC +"\" name=\"remoteIpAddress\" /&gt;"+"
&lt;parameter value=\""+http.REQ.HEADER("user-agent")+"\" name=\"userAgent\" /&gt;"+"
&lt;parameter value=\"" + HTTP.REQ.Cookie.Value("AuthKey") +"\" name=\"authenticationKey\" /&gt;"+"
&lt;/parameters&gt;"+"
&lt;/request&gt;"

This HTTP callout is required to advance the authentication process.  Within this particular step in the process, once this request/response transaction is successfully completed, a passcode will be generated and sent to the end-user by email, in this case.

  1. The next step in the process is entering the passcode for the 2nd factor authentication.

Responder Policy:

This policy triggers when an end-user enters the passcode for 2nd factor authentication.

Responder Action:

This responder action invokes an HTTP callout that submits the passcode entered by the end-user.


"HTTP/1.1 200 OK\r\nSet-Cookie: DeviceKey="+SYS.HTTP_CALLOUT(a7)+";expires=" + SYS.TIME.ADD(2592000).TYPECAST_TIME_AT+";Path=/\r\nConnection: close\r\n\r\n
&lt;script&gt;
window.onload=function() {
window.location=\"/vpn/anakam/get_zoo\";}
&lt;/script&gt;"

The response of the HTTP callout returns text that identifies the device key, which is an alphanumeric value.  This value is set as a cookie within the client’s web browser as “DeviceKey”.   There is also an expression that is configured to expire the cookie based on the current system time in addition to an amount of time for some time in the future:

  • SYS.TIME.ADD(292000).TYPECAST_TIME_AT

The responder action also delivers JavaScript to the client’s web browser to instruct it to send a request which logically aligns with the customized authentication process.

HTTP Callout:


"PUT /tfa/api/5.5/default/challenge/"+HTTP.REQ.COOKIE.VALUE("AuthKey")+" HTTP/1.1\r\nHost: 10.11.252.114:8080\r\nContent-Type: Application/XML\r\nConnection:"+" keep-alive\r\nContent-Length: 1000\r\nAuthorization: Basic YXBpLWFkbWluOkthbGVpZGEuMjAxNA=="+"
\r\n\r\n&lt;request command=\"execute\"&gt;"+"
&lt;parameters&gt;"+"
&lt;parameter value=\""+ Client.IP.SRC +"\" name=\"remoteIpAddress\" /&gt;"+"
&lt;parameter value=\""+http.REQ.HEADER("user-agent")+"\" name=\"userAgent\" /&gt;"+"
&lt;parameter name=\"user.passcode\" value=\""+HTTP.REQ.BODY(100).TYPECAST_LIST_T('=').GET(1)+"\" /&gt;
&lt;parameter value=\"true\" name=\"user.register.device\" /&gt;
&lt;parameter value=\"8\" name=\"user.register.device.duration\" /&gt;
&lt;parameter value=\"" + HTTP.REQ.Cookie.Value("AuthKey") +"\" name=\"authenticationKey\" /&gt;"+"
&lt;/parameters&gt;"+"
&lt;/request&gt;"

This HTTP callout submits the passcode that was entered by the end-user to the Anakam.TFA server.  It also enables user device registration.  Once the passcode is accepted successfully the Anakam.TFA server responds with a device key which is an alphanumeric value.  Successful reception of the device key also signifies that the authentication process is complete for an end-user who is connecting with an unregistered device.

  1. The last step required to complete the unregistered device authentication process is similar to step 3 in that it advances the authentication process to completion.  It also completes the authentication process for the NetScaler Gateway which results in the delivery of a authentication cookie by the NetScaler Gateway, “NSC_AAAC”.

Responder Policy:

This responder policy triggers last for unregistered device authentication.

Responder Action:

This responder action completes the authentication process by posting the LDAP credentials to “/cgi/login”.


"HTTP/1.1 200 OK\r\nSet-Cookie: Status2="+SYS.HTTP_CALLOUT(a4)+";Path=/\r\nConnection: close\r\n\r\n
&lt;script&gt;

function ns_getcookie(name)
{
 var cookie=document.cookie;
 if(cookie.length &gt; 0) {
 begin=cookie.indexOf(name+\"=\");"+"
 if(begin!=-1) {
 begin+=name.length+1;
 end=cookie.indexOf(\";\", begin);
 if(end==-1) end=cookie.length;
 return decodeURIComponent(cookie.substring(begin, end));;"+"
 }
 }
 return null;
}
window.onload=function() {
var request = new XMLHttpRequest();
request.open(\"POST\",\"/cgi/login\",false);"+"
request.setRequestHeader(\"Content-type\",\"application/x-www-form-urlencoded\");
request.send(\"login=\"+ns_getcookie(\"User\")+\"&amp;\"+\"passwd=\"+ns_getcookie(\"Password\"));"+"
window.location.href=\"/\";
}
&lt;/script&gt;"

The responder action above completes the authentication process by posting the user’s LDAP credentials to “/cgi/login”.  Posting the user’s LDAP credentials to “/cgi/login” correlates to the authentication policy that is bound to the NetScaler Gateway virtual server.  A successful post will result in the generation of an authentication cookie given by the NetScaler Gateway, “NSC_AAAC”.

Whether a device is registered or not depends on if the client’s web browser contains the Device Key cookie that the NetScaler uses to determine which authentication process to execute.  In essence, there are 2 authentication processes the NetScaler is configured to execute, unregistered device and registered device.  The following section outlines the authentication process for a registered device.

Registered Device Authentication

  1. End-user logs in to the NetScaler Gateway logon page.  A responder policy is configured to capture the username and then use that information for the authentication request to the Anakam.TFA server for the second factor authentication.  This policy is the same as the policy used in the first step of an unregistered device.

Responder Policy:

This policy triggers due to the index.html file modification.

Responder Action:

This responder action is configured to invoke an HTTP callout that initiates the 2nd factor authentication process.  The Anakam.TFA server responds with an authentication key that pertains to the particular user that is attempting to authenticate.  This authentication key is used to track the authentication process for a particular user.  The HTTP callout returns the authentication key as text, and then the responder action is configured to set the authentication key as a cookie so that it can be utilized accordingly throughout the authentication process.  The cookie for the authentication key is called “AuthKey”.  The name is arbitrary and can be given any other name that is acceptable to the organization.  In addition, this responder action utilizes JavaScript to instruct the end-user’s client browser to perform the following functions:

  1. A function that acquires the value of a cookie based on the cookie name
  2. An “If..Else” statement that determines if a Device Key cookie exists within the client’s web browser.  Based upon the result, the client’s web browser will initiate a HTTP request that will perform authentication based on a device key’s existence.  This section describes the authentication process with a device key.


"HTTP/1.1 200 OK\r\nSet-Cookie: AuthKey="+SYS.HTTP_CALLOUT(ana_logon)+"; Path=/\r\nSet-Cookie: User="+HTTP.REQ.BODY(200).TYPECAST_NVLIST_T('=','&amp;').VALUE("login")+";Path=/\r\nSet-Cookie: Password="+HTTP.REQ.BODY(200).TYPECAST_NVLIST_T('=','&amp;').VALUE("passwd")+";Path=/\r\nConnection: close\r\n\r\n
&lt;script&gt;
function ns_getcookie(name)
{
 var cookie=document.cookie;
 if(cookie.length &gt; 0) {
 begin=cookie.indexOf(name+\"=\");"+"
 if(begin!=-1) {
 begin+=name.length+1;
 end=cookie.indexOf(\";\", begin);
 if(end==-1) end=cookie.length;
 return decodeURIComponent(cookie.substring(begin, end));;"+"
 }
 }
 return null;
}
window.onload=function() {"+"
if (ns_getcookie(\"DeviceKey\")==null) {window.location = \"/vpn/anakam/ex_set_challenge\"; } else {window.location = \"/vpn/anakam/DeviceKey_Authentication\";}"+"
}
&lt;/script&gt;"

HTTP Callout:

Each request sent to the Anakam.TFA server requires an HTTP header called “Authorization”.  This header contains credentials required by the Anakam.TFA server to use the REST APIs.

  1. This next step in the process presents the device key to the Anakam.TFA server.  If successfully accepted, then end-user will be authenticated and will not be challenged or mandated to submit a passcode for the 2nd factor authentication.

Responder Policy:

This responder policy will trigger when the client’s web browser contains a device key cookie.

Responder Action:

This responder action is responsible for invoking the HTTP callout that will submit the device key to the Anakam.TFA server.


"HTTP/1.1 200 OK\r\nSet-Cookie: Auth_Status="+SYS.HTTP_CALLOUT(DeviceKey_Authentication_Status)+";Path=/\r\nConnection: close\r\n\r\n
&lt;script&gt;
window.onload=function() {
function ns_getcookie(name)
{
 var cookie=document.cookie;
 if(cookie.length &gt; 0) {
 begin=cookie.indexOf(name+\"=\");"+"
 if(begin!=-1) {
 begin+=name.length+1;
 end=cookie.indexOf(\";\", begin);
 if(end==-1) end=cookie.length;
 return decodeURIComponent(cookie.substring(begin, end));;"+"
 }
 }
 return null;
}
var request = new XMLHttpRequest();
request.open(\"POST\",\"/cgi/login\",false);"+"
request.setRequestHeader(\"Content-type\",\"application/x-www-form-urlencoded\");
request.send(\"login=\"+ns_getcookie(\"User\")+\"&amp;\"+\"passwd=\"+ns_getcookie(\"Password\"));"+"
window.location.href=\"/\";
}
&lt;/script&gt;"

This responder action creates a cookie that represents the status of the device key authentication request.  Its value validates if the device key authentication was successful or not.  This responder action also contains JavaScript that instructs the client’s web browser to POST the end-user’s LDAP credentials to “/cgi/login” which the NetScaler recognizes natively for authentication requests that come through the NetScaler Gateway virtual server.  Once successful, the NetScaler delivers a cookie called “NSC_AAAC” which represents successful authentication within the NetScaler Gateway virtual server.