In high security applications, the use of two-factor authentication (2FA) is often a hard requirement to provide enhanced security and meet more stringent compliance requirements.

With 2FA, users are required to provide two means of identification credentials for authentication. The most common example of 2FA is the use of traditional user name and password credentials in combination with a personal identification number (PIN) or token.

2FA can be implemented using RADIUS, which is an industry-standard protocol for providing authentication, authorization, and accounting services. The RADIUS server matches data from the authentication/authorization request with information in a trusted database, such as RSA SecurID, SQL or LDAP. If a match is found and the user’s credentials are correct, the RADIUS server sends a “success” response to the client, which is then allowed access to a corporate resource. A similar solution can be deployed using a Web Authentication server, which connects to a trusted backend database with user security information, where user credentials are sent through HTTP headers.

NetScaler version 10.5 and later with the AAA-TM feature can now authenticate users to a Web Authentication server, providing the credentials that the web server requires in an HTTP request and subsequently analyzing the web server response to determine that user authentication was successful.

Previously, a similar exercise would be done using the HTTP Callout feature, where a client would send the user name and password through HTTP headers in the request.  A typical implementation of an HTTP callout would include creating an HTTP callout on the appliance and configuring it with details about the external server and other required parameters, configuring a responder policy to analyze the response and then creating a callout agent on the remote server.

The new Web Authentication feature now simplifies this process, where configuration is similar to creating a standard authentication server and a policy that can be bound to a virtual server for single FA or 2FA.

As with other types of authentication policies, a Web authentication policy is comprised of an expression and an action. After creating an authentication policy, you bind it to an authentication virtual server and assign a priority to it. When binding it, you also designate it as either a primary or a secondary policy.

To set up web-based authentication with a specific web server, first you create an Authentication WEB Server that contains the following items:

  • Name—Name for the Web Authentication action.
  • Web Server IP Address— The IP address of the authentication Web server.
  • Port— The port of the authentication Web server.
  • Protocol—HTTP (for unencrypted web authentication) or HTTPS (for encrypted web authentication).
  • HTTP Request Expression— An expression in NetScaler default syntax that contains the user’s credentials in the format that the Web server expects.
  • Expression to validate the Authentication—An expression in NetScaler default syntax that matches the web server response string that signifies that the user authenticated successfully.

Authentication Rule & Expression to validate the Authentication are the most important items in the list above, which have to be formatted precisely to ensure the NetScaler request and response matches the exact POST expression that the Web server expects. In this example we will use a sample POST request and response to configure Web authentication on NetScaler 10.5. At high level we need to complete following 5 steps:

  1. Create a Netscaler Gateway VIP or AAA-TM Virtual Server and associated configuration.
  2. Create Web authentication server “HTTP Request Expression” & “Expression to validate the Authentication”
  3. Create Web authentication server and tie in the details from step 2.
  4. Create Web authentication policy and associate it with the Web Authentication Server.
  5. Bind the Web Authentication Policy to the Netscaler Gateway or AAA-TM VIP in question.

We will assume, at this point, that you are implementing this solution because of a specific requirement where the credentials from Netscaler Gateway or AAA-TM needs to be sent to a specific server in a specific manner that requires this approach.

At this point, one should also validate that the basic Netscaler Gateway ICA proxy functionality is working with standard LDAP based authentication. Once done, it’s now time to get to the exciting stuff!

Step 1: Create Web authentication server “HTTP Request Expression” & “Expression to validate the Authentication”

a)    Capture the original POST request that the Web server expects

The Web server administrator should ideally provide this to you otherwise you could use tools such as Wireshark to run a trace against the server to determine the POST request. Here is a sample trace:

Search for “http” traffic in your trace and look for the traffic that corresponds to you Web server with a POST request, right click and select “Follow TCP Stream” which will show you the POST request.

Note: If your Web server is running on secure port 443, you’ll not be able to inspect the stream. You may have to look at your Web server logs to determine the POST request or subsequently load the private key in Wireshark to decrypt it on the fly. Instructions on decrypting secure traces can be found here.

Note from the POST request that the Web server expects 2 dynamic fields – EmployeeID & Token.

b)   Format the HTTP request expression accordingly

Once you obtain the POST request, it’s time to format the “HTTP Request Expression” that will be used to create Web authentication server. For this you’ll need to know basics of HTTP expressions and Java strings.

Here is the POST request from the trace above –

——————————————————————————————————————————–

POST https://webtoken.mylab.com/Desarrollos/token.nsf/WebServiceToken?OpenWebService HTTP/1.1

Accept-Encoding: gzip,deflate

Content-Type: text/xml;charset=UTF-8

SOAPAction: “”

User-Agent: Jakarta Commons-HttpClient/3.1

Host: webtoken.mylab.com

Content-Length: 256

<soapenv:Envelopexmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”xmlns:urn=”urn:webtoken.mylab.com>

<soapenv:Header/> <soapenv:Body>

<urn:employeeID>ccsuser1</urn:employeeID>

<urn:token>12345</urn:token>

</soapenv:Body> </soapenv:Envelope>

——————————————————————————————————————————–

We can now use the Netscaler PI expression logic to POST to the specific server in question. The server and path is: https://webtoken.mylab.com/Desarrollos/token.nsf/WebServiceToken?OpenWebService.

We also need to append several attributes to ensure that the POST expression submitted by the Netscaler matches that of a successful transaction (captured below). Please note the use of “+” to concatenate expressions and “\r\n” to indicate the carriage return and newline functions. This HTTP Web Authentication would also need to pass the username and password credentials that user typed in the Netscaler at the AAA-TM page. This is explained further below.

It should be noted that this type of expression may take a few tries and traces in Wireshark to ensure that the current expression is being sent to the backend server.

Here is how the formatted expression will look –

——————————————————————————————————————————–

“POST https://webtoken.mylab.com/Desarrollos/token.nsf/WebServiceToken?OpenWebService HTTP/1.1\r\n”+”Accept-Encoding: gzip,deflate\r\n”+”Content-Type: text/xml;charset=UTF-8\r\n”+”SOAPAction: \”\”\r\n”+”User-Agent: Jakarta Commons-HttpClient/3.1\r\n”+”Host: webtoken.mylab.com\r\n”+”Content-Length: 326\r\n\r\n”+”<soapenv:Envelope xmlns:soapenv=\”http://schemas.xmlsoap.org/soap/envelope/\”xmlns:urn=\”urn:webtoken.mylab.com\”> <soapenv:Header/> <soapenv:Body> <urn:employeeID>\r\n”+http.req.body(http.req.content_length).after_str(“login=”).before_str(“&”)+”</urn:employeeID> <urn:token>\r\n”+http.req.body(http.req.content_length).after_str(“passwd=”)+”</urn:token> </soapenv:Body> </soapenv:Envelope>\r\n”

——————————————————————————————————————————–

By Default, the NetScaler send user name and password in following format below as part of a POST payload.

——————————————————————————————————————————–

login=test&passwd=test123

——————————————————————————————————————————–

Netscaler PI expressions can be used  to capture the EmployeeID by using the expression:  –

——————————————————————————————————————————–

http.req.body(http.req.content_length).after_str(“login=”).before_str(“&”)

——————————————————————————————————————————–

And following to capture the Token –

——————————————————————————————————————————–

http.req.body(http.req.content_length).after_str(“passwd=”)

——————————————————————————————————————————–

c)    Capture original POST response from the WEB server

Next step is to create the Expression to validate the Authentication which is a POST response Web server sends in return during authentication, this determines if the user authentication is successful or not. Similar to POST request, now you’ll need to capture the POST response from the Web server. You can obtain this using the same procedure we used to capture the POST request using a network trace. Here is a sample response for successful credential validation:

——————————————————————————————————————————–

HTTP/1.1 200 OK 

Server: Lotus-Domino 

Date: Mon, 11 May 2015 22:50:12 GMT 

Content-Type: text/xml; charset=utf-8 

Content-Length: 542 

<?xml version=”1.0″ encoding=”UTF-8″?> 

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“> 

 <soapenv:Body> 

  <consultaTokenReturn xmlns=”urn:webservice.gruposalinas.com”>&lt;ConsultaToken&gt;&lt;Respuesta&gt;&lt;Estatus&gt;0&lt;/Estatus&gt;&lt;Descripcion&gt;Autentificacion completada correctamente&lt;/Descripcion&gt;&lt;/Respuesta&gt;&lt;/ConsultaToken&gt;</consultaTokenReturn> 

 </soapenv:Body> 

</soapenv:Envelope>

——————————————————————————————————————————–

d)   Format the “Expression to validate the Authentication” accordingly

Using the POST response you captured above, format the validation expression, which will look like this –

——————————————————————————————————————————–

http.res.body(1000).CONTAINS(“Estatus&gt;0”)

——————————————————————————————————————————–

The success criteria should match the immediate response after the POST and not any subsequent requests. The same logic applies for HTTP Callout type expression logic as well.

Step 2: Create Web authentication server

Putting it all together, we are now going to create a Web Auth Action via the command line referencing the server and the port with the POST expression that we have constructed above. 

Using the command line interface –

——————————————————————————————————————————–

add authentication webAuthAction Web_Auth_Server -serverIP 172.21.0.18 -serverPort 80 -fullReqExpr q{“POST https://webtoken.mylab.com/Desarrollos/token.nsf/WebServiceToken?OpenWebService HTTP/1.1\r\n”+”Accept-Encoding: gzip,deflate\r\n”+”Content-Type: text/xml;charset=UTF-8\r\n”+”SOAPAction: \”\”\r\n”+”User-Agent: Jakarta Commons-HttpClient/3.1\r\n”+”Host: webtoken.mylab.com\r\n”+”Content-Length: 326\r\n\r\n”+”<soapenv:Envelope xmlns:soapenv=\”http://schemas.xmlsoap.org/soap/envelope/\”xmlns:urn=\”urn:webtoken.mylab.com\”> <soapenv:Header/> <soapenv:Body> <urn:employeeID>\r\n”+http.req.body(http.req.content_length).after_str(“login=”).before_str(“&”)+”</urn:employeeID> <urn:token>\r\n”+http.req.body(http.req.content_length).after_str(“passwd=”)+”</urn:token> </soapenv:Body> </soapenv:Envelope>\r\n”} -scheme http -successRule “http.RES.body(1000).CONTAINS(\”Estatus&gt;0\”)”

——————————————————————————————————————————–

Using the configuration utility –

Navigate to Security -> AAA – Application Traffic -> Policies -> Authentication – > Basic Policies -> WEB -> Servers and click on Add

defaultAuthenticationGroup is the default group that is chosen when the authentication succeeds in addition to extracted groups.. If this isn’t configured on your Web server, please leave it blank and continue.

Step 3: Create Web authentication policy

A Web Authentication policy can used with your expression of choice to trap the profile. A standard “true” or “ns_true” is used to always trap the request and associated response if activated.

Using the command line interface –

——————————————————————————————————————————–

add authentication webAuthPolicy Web_Auth_Policy -rule ns_true -action Web_Auth_Server

——————————————————————————————————————————–

Using the configuration utility –

Navigate to Security -> AAA – Application Traffic -> Policies -> Authentication – > Basic Policies -> WEB -> Policies and click on Add

You can bind this Web authentication policy to a NetScaler Gateway VIP to validate authentication.

——————————————————————————————————————————–

bind vpn vserver _Test_NetScalerGateway_VIP -policy Web_Auth_Policy -priority 100

——————————————————————————————————————————–

Hope this helps you get started with the Web authentication with NetScaler, however you may need to perform advanced expressions and policy configurations depending on your use case such as 2 factor authentication or when the Web server expects more fields than just EmployeeID and Token.