Saturday, October 18, 2008

Incorporating reCAPTCHA into your Struts 2 + Spring Application

Who thought that that CAPTCHA implementations are only good for preventing spam? It turns out that the reCAPTCHA project from Carnegie Mellon University also does some common good. Developed by the same people that coined the term CAPTCHA, the project is also being used to help digitizing old books and publications (Including my favorite US Newspaper). The process is further explained here.

In addition to that it is a slick CAPCHA implementation as well, that you can incorporate freely into your web applications. There are APIs available for various languages including Java, Ruby and Python.

For my Struts 2 + Spring project I am using reCAPTCHA for the user registration page. The user fills out the registration but before s(he) submits the form a reCAPCHA form field has to be filled out, which means recognizing 2 words that are part of an image and retyping those two words into a form field. Upon form submission, code in my Struts 2 action calls the reCAPCHA Java API and validates the two words that were previously entered by the user.

Setting everything up has been easy and involves the following steps:
  • Signup for a reCAPTCHA account and generate the necessary keys for your site (similar to setting up Google Maps)
  • Add the recaptcha4j library to your project
  • Add some Javascript code to your JSP
  • Define the main recaptcha4j bean in your Spring ApplicationContext.xml file
  • Configure your Struts 2 Actions to process and validate the reCAPCHA form data
In your applicationContext.xml file you need to add the following bean definition:

<bean id="reCaptcha" class="net.tanesha.recaptcha.ReCaptchaImpl">
<property name="privateKey" value="your private key"/>
<property name="publicKey" value="your public key"/>
<property name="recaptchaServer" value="http://api.recaptcha.net"/>
<!-- For SSL use:
<property name="recaptchaServer" value="https://api-secure.recaptcha.net"/> -->
<property name="includeNoscript" value="false"/>
</bean>

In your jsp:




Setup your Struts 2 action to process two form parameters:

  1. recaptcha_challenge_field

  2. recaptcha_response_field


Then in your actual action code you validate those 2 token by calling:

public class SignupAction {
private User user;

private String recaptcha_challenge_field;
private String recaptcha_response_field;
private @Autowired ReCaptcha reCaptcha;

public String execute() {

ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(
ServletActionContext.getRequest().getRemoteHost(),
recaptcha_challenge_field,
recaptcha_response_field);

if (!reCaptchaResponse.isValid()) {
addActionError("Not a good CAPTCHA.");
return INPUT;
}

...process the user registration form etc.

return SUCCESS;

}

...your setters
}

That's it. These should be all the basic steps necessary to get you going.

Here are some further resources:

http://wheelersoftware.com/articles/recaptcha-java-2.html
http://tanesha.net/projects/recaptcha4j/
http://recaptcha.net/apidocs/captcha/

No comments: