Top

CAPTCHA : Form Validation - Creation of Dynamic image in Java

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 4 out of 5)
Loading ... Loading ...

Posted the by admin

here is a sample application used to challenge users to be able to see if they are a bot or not. Subscription forms are always needing this kind of tools for server security. The goal is to build a picture containing text, and to compare user’s input with it.
It is very difficult to build a bot able to go throught that kind of security (very difficult doesn’t mean impossible!).

Here is a sample of generated picture :

How it works :

To work is application is composed of :

  • A servlet used to generate the picture and write its value inside session.
  • A JSP file used to compare session’s value and user input.

This sample is running and has been tested on Tomcat 5.5.7 JDK 5.

1) The Servlet’s code :

 
/* * Created on 28 mars 2005 * */
package com.utils.dynimage;
 
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.util.*;
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import java.awt.font.*;
import javax.imageio.*;
import java.awt.geom.*;
 
/** * @author Eric * */
public class GetDynImage extends HttpServlet {
 
	public void init() throws ServletException {
		//System.out.println("Servlet started");
	}
 
	public void destroy() {
		//System.out.println("Servlet is stopping now");
	}
 
	protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
		doGet(arg0, arg1);
	}
 
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
		String text = getRandomText();
 
		// String saving in HTTP session
		HttpSession session = request.getSession(true);
		session.setAttribute("dynImageTxt", text);
		String font_file = getServletContext().getRealPath ("WEB-INF/ttf/acmesa.ttf" );
		float size = 50.0f;
		Color background = Color.white;
		Color color = Color.black;
 
		try {
			Font font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream(font_file));
			font = font.deriveFont(size);
			BufferedImage buffer = new       BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
			Graphics2D g2 = buffer.createGraphics();
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,       RenderingHints.VALUE_ANTIALIAS_ON);
			FontRenderContext fc = g2.getFontRenderContext();
			Rectangle2D bounds = font.getStringBounds(text,fc);
 
			// Trying to find the size of the picture
			int width = (int) bounds.getWidth();
			int height = (int) bounds.getHeight();
 
			// preparing output
			buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			g2 = buffer.createGraphics();
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,       RenderingHints.VALUE_ANTIALIAS_ON);
			g2.setFont(font);
			g2.drawString(text,0,(int)-bounds.getY());
 
			// Set content type et get de l'output stream
			response.setContentType("image/jpeg");
			OutputStream os = response.getOutputStream();
 
			// Output image as a JPG picture.
			ImageIO.write(buffer, "jpg", os);
			os.close();
 
		} catch (Exception e) {
			// Error catching... oups empty
		}
	}
 
	/***
	*
	* Method used to get a random UpperCase text of 5 letters.
	*
	* @return	String text.
	*/
	private String getRandomText () {
 
		// Creation of a random text
		int length = 5;
		char[] array = new char[ length ];
		char[] chars = new char[26];
 
		//for (int i = 0; i < 26; i ++) {chars[i] = (char) (97 + i);chars[i + 26] = (char) (65 + i);}
 
		// Creation of an Array with Upper Caps letters.
		for (int i = 0; i < 26; i ++) {
			chars[i] = (char) (97 + i);
		}
		Random random = new Random ();
 
		for (int i = 0; i < length; i ++) {
			array[i] = chars[random.nextInt (chars.length)];
		}
 
		// Default parameters
		return new String (array);
 
	}
}

2) Validation of the input :

// Lecture de la session, de l'attribut captcha
HttpSession session = request.getSession(true);
String value = (String) session.getAttribute("dynImageTxt");
 
// Reading "imgValue" field from input form.
String formValue = request.getParameter("imgValue");
 
if (formValue.toLowerCase().equals(value.toLowerCase())) {
	// Good value job here !!!!
} else {
	// Bad value job here !!!!
}


Be Aware, that if your server is behing a load balancing hardware, you should take care of keeping the user on the same server. If not, CAPTCHA would never be validated.

Community Area - You can add comments here




Bottom