Integrating CAPTCHA authentication technologies with WebSEAL

A reference implementation by using WebSEAL EAI

CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a popular mechanism used in Web sites to ensure humans only are interacting with the security functions of the Web site. CAPTCHA does this by producing images that include embedded numbers and letters that are not easily interpreted by automation tools. This article provides a solution and reference implementation of how to integrate CAPTCHA with IBM® Tivoli® Access Manager (TAM) WebSEAL.

Rick Wu (rickwu@tw.ibm.com), Software Engineering Manager, CSDL, IBM Taiwan

Rick Wu photoRick Wu is a Software Engineering Manager at IBM China Software Development in Taipei, Taiwan. His areas of expertise include pervasive computing, telecom solutions, and RFID solutions. He is now working on Lotus Expeditor development and test.



Rebecca Chen (rchen@tw.ibm.com), Staff Software Engineer, CSDL, IBM Taiwan

Rebecca ChenRebecca Chen is a Staff Software Engineer at IBM China Software Development Lab in Taipei, Taiwan. Her areas of expertise include pervasive computing, telecom solutions, and RFID solutions. She leads a team of Software Engineers working on performance tuning for IBM Telecom solution products.



12 February 2008

1 Overview

Many hackers attack Web sites by brute force attempting to try the ID and password via programs or automation software. As a definition found in Wikipedia, CAPTCHA is a type of challenge-response test to ensure the user is human. The term CAPTCHA was coined in 2000 by Luis von Ahn, Manuel Blum, Nicholas J. Hopper (all of Carnegie Mellon University), and John Langford (then of IBM). A common type of CAPTCHA requires that the user type the letters or numbers of a distorted image, sometimes with the addition of an obscured sequence of letters or digits that appears on the screen. This technology can reduce the risk of your authentication scheme or customer registration system from being subjected to an automated denial of service operation (whether a legal or illegal operation).

This article demonstrates how to use CAPTCHA in the login form of WebSEAL. We will use the WebSEAL External Authentication Interface (hereafter called EAI) to implement the solution and provide a sample of how to introduce the use of CAPTCHA to a WebSEAL deployment.

The contents of this article include the following:

  • The solution architecture and how it works in WebSEAL
  • How to test the solution

2 How the solution works in WebSEAL

2.1 High level solution architecture and traffic flow

The solution is composed of three components that run on an IBM WebSphere® Application Server. The first component is a login form implemented by using the Java™ Server Page (JSP) and servlet. The login form calls the second component, CAPTCHA image generator, to generate a CAPTCHA random number image to be displayed in the login form. The third component is the External Application Interface (EAI) application. The EAI application is a servlet that checks to ensure the CAPTCHA random number, user ID, and password are valid. This article uses the snoop servlet provided by WebSphere Application Server for testing the back-end application. If the EAI authentication succeeds, WebSEAL will route the HTTP request to the testing snoop servlet. The high-level solution architecture is shown in Figure 1 below.

Figure 1. High level solution architecture
High level solution architecture

The HTTP traffic flow is described below.

  1. The browser connects to a back-end application URL protected by WebSEAL. This means that the user needs to pass the WebSEAL authentication and authorization before accessing the protected URL.
  2. The HTTP request arrives at WebSEAL. WebSEAL finds that the URL needs authentication and authorization before accessing it. Then, WebSEAL asks the browser to redirect to the login form URL.
  3. The browser gets the redirect request from WebSEAL and then connects to the login form URL.
  4. The login form calls the CAPTCHA image generator to generate a random number CAPTCHA image and then send the login form (with ID and password input field and CAPTCHA random number image) back to the browser. At the same time, the login form JSP/Servlet will store the random number in the HTTP session.
  5. The user inputs the user ID, password, and the random number of the CAPTCHA image. After the user clicks the submit or login button, the browser sends the ID, password, and the random number to the WebSEAL, this information is passed to the EAI application.
  6. The EAI application checks to ensure the user ID, password, and the random number are correct. (The EAI application can retrieve the random number from the HTTP session and compare it with the number input by the user.)
  7. If the details are valid, the EAI application inserts the TAM user ID in the response HTTP header and sends the response to WebSEAL.
  8. WebSEAL gets the HTTP response from the EAI application, extracts the user ID from the HTTP header, performs the authorization for the user, and then creates a session for the user.
  9. WebSEAL sends a redirect request to the browser and asks the browser to redirect to the protected URL that the user inputs in Step 1.
  10. The browser gets the redirect request from the WebSEAL and then connects to the protected URL. The URL request arrives at WebSEAL again. Because the user has already passed the authentication, WebSEAL authorizes the request and routes the URL request to the back-end application (testing snoop servlet).
Figure 2. HTTP traffic flow
HTTP traffic flow

2.2 WebSEAL configurations

Now, let's go through the details to configure WebSEAL for the solution given in this article.

First, create a junction, /backend, from the WebSEAL Servers for the protected backend applications as shown in Listing 1.

Listing 1. Create junctions for back-end application
# pdadmin -a sec_master -p password
pdadmin sec_master> server task default-webseald-pvc34.tw.ibm.com create -t tcp 
-h pvc33.tw.ibm.com /backend

Second, create a junction, /eai, from the WebSEAL Servers to the EAI applications (JSP/Servlet) as shown in Listing 2.

Listing 2. Create junctions for the EAI application
# pdadmin -a sec_master -p password
pdadmin sec_master> server task default-webseald-pvc34.tw.ibm.com create -t tcp 
-h pvc33.tw.ibm.com -c iv_user /eai

Last, the EAI applications (JSP and Servlet) should not be in the protected domain, because unauthenticated users need to access these URLs. In Listing 3, it shows how to create the unauthenticated ACL for allowing unauthenticated access to the junction.

Listing 3. Create the ACL for the unauthenticated users
pdadmin sec_master> acl create unauth
pdadmin sec_master> acl modify unauth set group iv-admin TcmdbsvaBRrxl
pdadmin sec_master> acl modify unauth set group webseal-servers Tgmdbsrxl
pdadmin sec_master> acl modify unauth set user sec_master TcmdbsvaBRrxl
pdadmin sec_master> acl modify unauth set any-other Trx
pdadmin sec_master> acl modify unauth set unauthenticated Trxc

Then, attach the above ACL to the EAI junction as shown in Listing 4.

Listing 4. Attach the ACL to the junction for the EAI application
pdadmin sec_master> acl attach /WebSEAL/pvc34.tw.ibm.com-default/eai unauth

Now, we’re ready to start the last part of configuring the EAI application with WebSEAL. It is configured through the WebSEAL configuration file, webseald-default.conf. This file is located in the /opt/pdweb/etc/ directory on the Linux® and UNIX® platforms

First, enable the EAI authentication for HTTP and HTTPS sessions as shown in Listing 5.

Listing 5. Enable the EAI authentication
[eai]
eai-auth = both

Next, configure the authentication levels for step-up authentication. All levels of authentication will map to the EAI application:

Listing 6. Enable the EAI authentication
[authentication-levels]
level = unauthenticated
level = password
level = ext-auth-interface 

The next step is to specify the EAI authentication interface library in WebSEAL configuration file. Table 1 shows the EAI authentication module of different operating system.

Table 1. EAI authentication module
Operating SystemModule
Solaris™libeaiauthn.so
AIX®libeaiauthn.a
HPUXlibeaiauthn.sl
Linuxlibeaiauthn.so
Windows®eaiauthn.dll

As seen in Listing 7, this article chooses libeaiauthn.a as the authentication module because it uses WebSEAL on the AIX platform.

Listing 7. Configure the EAI authentication module
[authentication-mechanisms]
# EXTERNAL AUTHENTICATION INTERFACE
ext-auth-interface = /opt/pdwebrte/lib/libeaiauthn.a

The next step is to configure the trigger URL so that WebSEAL can know if the URL from the browser is for EAI authentication. In this example, the EAI application URL is http://pvc34.tw.ibm.com/eai/csp/ValidateLogin. Therefore, set the trigger URL to be /eai/csp/ValidateLogin* as shown Listing 8.

Listing 8. Configure the trigger URL
[eai-trigger-urls]
trigger = /eai/csp/ValidateLogin*

Because the login form JSP/Servlet is not a local HTML file on the WebSEAL server, it is necessary to enable the local response redirect URL as shown in Listing 9.
(Note)The login-response-redirect is designed to handle all errors and login conditions, but this example just shows the handling of the login sequence.

Listing 9. Enable the local response redirect
[acnt-mgt]
enable-local-response-redirect = yes

After enabling local response redirection, the next step is to provide the URL to our login form JSP or Servlet that will handle the requests for local responses. In the example below, the login form URL is http://pvc34.tw.ibm.com/eai/csp/LoginController.

Listing 10. Set the local response URL
local-response-redirect-uri = /eai/csp/LoginController

Because the EAI application put the user ID in the HTTP response header, it is necessary to set the header name for the WebSEAL, so that WebSEAL can extract the authenticated user ID from the specified HTTP response header. This article uses the default HTTP header name "am-eai-user-id" as shown in Listing 11. If the header name in the WebSEAL configuration file is changed, the same HTTP response header name needs to be used by the EAI application. This is explained in Listing 15 of Section 2.3, WebSEAL EAI implementation.

Listing 11. Set the EAI user ID header name
# EAI USER ID header names
eai-user-id-header = am-eai-user-id

Next, restart the WebSEAL server by using the command shown in Listing 12 in order to make the changes effective.

Listing 12. Restart WebSEAL Server
# pdweb restart

2.3 WebSEAL EAI implementation

This section details the reference implementation. The source codes are available in the download section. To generate the CAPTCHA image, an open source tool, Jcaptcha, is used in this article. Figure 3 shows the sequence diagram of the reference implementation.

Figure 3. Sequence diagram of the implementation
Sequence diagram of the implementation
  1. The browser connects to a back-end application URL protected by WebSEAL. This means the user needs to pass the WebSEAL authentication and authorization before accessing the protected URL.
  2. The HTTP request arrives at WebSEAL. WebSEAL finds that the URL needs authentication and authorization before accessing it. Then, WebSEAL asks the browser to redirect to the servlet, LoginController.java.
  3. The browser gets the redirect request from WebSEAL and then connects to the servlet, LoginController.java.
  4. The LoginController.java servket requests a new CAPTCHA image, puts the random number in the HTTP session, and then forwards the request to dWorkLogin.jsp. The details of how LoginController.java gets a new CAPTCHA image are described in Figure 4 below.
  5. The dWorkLogin.jsp generates the Login form (ID, password, CAPTCHA image) and sends it back to the browser
  6. The user inputs the user ID, password, and the random number of the CAPTCHA image. After the user clicks the submit or login button, the browser sends the ID, password, and the random number to the WebSEAL. Then WebSEAL passes the information to the EAI application, servlet ValidateLogin.java for verification.
  7. The ValidateLogin.java servlet checks to ensure the user ID, password, and the random number are correct. (ValidateLogin.java can retrieve the random number from the HTTP session and compare it with the number input by the user.)
  8. After passing the checking, ValidateLogin.java inserts the TAM user ID in the response HTTP header and sends the response to WebSEAL.
  9. WebSEAL gets the HTTP response from ValidateLogin.java, extracts the user ID from the HTTP header, performs the authorization for the user, and then creates a session for the user.
  10. WebSEAL sends a redirect request to the browser and asks the browser to redirect to the protected URL that the user inputs in Step 1.
  11. The browser gets the redirect request from the WebSEAL and then connects to the protected URL. The URL request arrives at WebSEAL again. Because the user has already passed the authentication and authorization, WebSEAL routes the URL request to the back-end application (testing snoop servlet).
Figure 4. Flow chart of CAPTCHA generator
Flow chart of CAPTCHA generator
  1. When the first HTTP request arrives, LoginController.java requests a CAPTCHA image.
  2. The CAPTCHA generator checks whether the total number of CAPTCHA images in its pool is less than M (configurable value).
  3. If the value is less than M, CAPTCHA generates N (configurable value) CAPTCHA images in the pool.
  4. Then, it gets the first CAPTCHA image from the pool and returns it to LoginController.java.

The following sections go through the codes of LoginController.java, dWorkLogin.jsp, and ValidateLogin.java.

The servlet, LoginController.java, is the local response redirect URL configured in the configuration file of WebSEAL. It is the entry point of login form generating. First, it gets one CAPTCHA image and puts the random number in the HTTP session (for the future access by the EAI servlet, ValidateLogin.java.). Then, it forwards the HTTP request to the login form generator, dWorkLogin.jsp.

Listing 13. CAPTCHA image generator (Servlet) - LoginController.java
...
...
...
//Call CAPTCHA image generator to generate CAPTCHA images
String imagePath = this.getServletContext().getRealPath(Constant.getImagePath()) + "/";
ImagePool imagePool = ImagePool.getInstance(imagePath);
MagicNumber magicNumber = null;
...
...
...
magicNumber = (MagicNumber) req.getSession().getAttribute(Constant.getIdentityKey());
if (magicNumber != null) {
    imagePool.delImage(magicNumber.getImage());
    System.out.println("Delete "+magicNumber+ " image file from LoginController.");
}
magicNumber = imagePool.getImage();
//Put the magic number of the CAPTCHA image in the HTTP session
req.getSession().setAttribute(Constant.getIdentityKey(), magicNumber);
String imageFile = magicNumber.getImage();
//Put the imageFile in the request attribute and pass it to dWorkLogin.jsp
req.setAttribute(Constant.getImageFileName(), imageFile);
RequestDispatcher rd = this.getServletContext().
                       getRequestDispatcher("/"+Constant.getLoginJSP());
rd.forward(req,resp);

The JSP, dWorkLogin.jsp, generates the login form including ID, password fields, and CAPTCHA image. Then, it sends the login form back to the browser and waits for the input of the user. Please pay attention to the form action of the HTML. It should be set to the EAI application/servlet URL. After the user inputs the ID, password, and the random number, and clicks the submit button, this data is sent to the EAI application/servlet, ValidateLogin.java for verification.

Listing 14. Login Form JSP - dWorkLogin.jsp
...
...
...
<BR>
 
<FORM METHOD=POST ACTION="/eai/csp/ValidateLogin">
<FONT SIZE="+2">
<TABLE BORDER="0" WIDTH="400">
<TR>
<TD ALIGN="LEFT"><UL><LI>Username</LI></UL></TD>
<TD><INPUT NAME="username" SIZE="15"></TD>
...
...
...

The EAI application/servlet, ValidateLogin.java, is used to check the ID, password, and whether the number input by the user matches the random number generated by LoginController.java. First, it extracts the random number from the HTTP session and then compares it with the number input by the user. Then, it will check whether the ID and password are valid or not. If both of the checks succeed, it will insert the user ID in the HTTP response header, am-eai-user-id, configured in the WebSEAL configuration file as described in Listing 11 of the previous section. If either check fails, it redirects to the servlet, LoginController.java, in order to show the login form again on the browser.

Listing 15. EAI Application (Servlet) - ValidateLogin.java

Click to see code listing

Listing 15. EAI Application (Servlet) - ValidateLogin.java

String ivuser = null;
HttpSession session = req.getSession();
boolean checkResult = false;
//Extract the random magic number of the CAPTCHA image from the HTTP session//And then compare it with the number input by the user.
if (session != null) {
MagicNumber magicNumber = (MagicNumber) session.getAttribute(Constant.getIdentityKey());
    session.removeAttribute(Constant.getIdentityKey());
    if (magicNumber != null) {
        checkResult = magicNumber.check(req.getParameter(Constant.getIdentityKey()));
        String imagefile = magicNumber.getImage();
        this.imagePool.delImage(imagefile);
        System.out.println("Delete image file " + imagefile);
    }
}
//If the random magic number checks fail, then go back to the login form again. 
if (!checkResult) { 
    //Redirect to the login controller page again!
    String url = "./"+Constant.getLoginURL();
    System.out.println("++++++++++ CAPTCHA magic number checking fail. ++++++++++");		
    resp.sendRedirect(resp.encodeRedirectURL(url));	
    return; // CAPTCHA check fail
}
//Then, check the user id and password here
...
...
...
//If both the random magic number checking and id/password checking succeed//Set the user ID to the HTTP response header "am-eai-user-id" //You could change the header name in webseald-default.conf 	
resp.setHeader("am-eai-user-id", id);

3 Test the solution

As mentioned earlier, this article uses the snoop servlet, provided by WebSphere Application Server as the testing back-end application. This application is deployed with URL http://pvc33.tw.ibm.com/snoop. In section 2.2, a junction, /backend, has been configured in the WebSEAL server (that is,, pvc34.tw.ibm.com). Therefore, the URL, http://pvc34.tw.ibm.com/backend/snoop, could connect to the protected back-end application. If the solution works, the login form (with ID field, password field, and CAPTCHA image) is shown on the browser as Figure 5 below. After inputting the correct ID, password and the number shown in the CAPTCHA image, the result of the snoop servlet might be shown as figure 6 below.

Figure 5. Login Form with CAPTCHA image
Login Form with CAPTCHA image
Figure 6. The successful result - snoop servlet is shown
The successful result

4 Summary

This article shows how to implement a CAPTCHA login form in WebSEAL. It uses EAI to implement the solution because it is a very good function that allows us to extend the user authentication mechanism.

Acknowledgements

The authors would like to thank Andrew Tsai (andrewt@ca.ibm.com) for his help to setup the testing environments.


Download

DescriptionNameSize
Sample source codes for this articleWebSEALCAPTCHA.zip24KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Security on developerWorks


  • Bluemix Developers Community

    Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.

  • Security

    Pragmatic, intelligent, risk-based IT Security practices.

  • DevOps Services

    Software development in the cloud. Register today to create a project.

  • IBM evaluation software

    Evaluate IBM software and solutions, and transform challenges into opportunities.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Security, Tivoli (service management), Tivoli
ArticleID=280228
ArticleTitle=Integrating CAPTCHA authentication technologies with WebSEAL
publish-date=02122008