Monday 29 September 2014

How to Change the JCaptcha configurations?

Set up JCAPTCHA to your application

In this example, a simple Java servlet is used to generate a jcaptcha image, that user must enter letters appearing in the jcaptcha image
  • Add the following servlet path and URL pattern to your web.xml in your application:
<servlet>
        <servlet-name>jcaptcha</servlet-name>
        <servlet-class>com.struts2.security.ImageCaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
        <servlet-name>jcaptcha</servlet-name>
        <url-pattern>/jcaptcha.jpg</url-pattern>
</servlet-mapping>
  • Add the follwing HTML script in your jsp
  <img src="jcaptcha.jpg" /> <input type="text" name="jcaptcha" value="" />
  •  Servlet to generate Jcaptcha image.
       byte[] captchaChallengeAsJpeg = null;
       // the output stream to render the captcha image as jpeg into
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        try {
        // get the session id that will identify the generated captcha.
        //the same id must be used to validate the response, the session id is a good candidate!
        String captchaId = httpServletRequest.getSession().getId();
        // call the ImageCaptchaService getChallenge method
            BufferedImage challenge =null;
            if(httpServletRequest.getParameter("sm")!=null){
               /* challenge =CaptchaSmallServiceSingleton.getInstance().getImageChallengeForID(captchaId,
                        httpServletRequest.getLocale());*/
            }else{
                challenge =CaptchaServiceSingleton.getInstance().getImageChallengeForID(captchaId,
                            httpServletRequest.getLocale());
            }
            //System.out.println(challenge);
            // a jpeg encoder
            JPEGImageEncoder jpegEncoder =
                    JPEGCodec.createJPEGEncoder(jpegOutputStream);
            jpegEncoder.encode(challenge);
        } catch (IllegalArgumentException e) {
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        } catch (CaptchaServiceException e) {
            httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
                   
        captchaChallengeAsJpeg = jpegOutputStream.toByteArray();

        // flush it in the response
        httpServletResponse.setHeader("Cache-Control", "no-store");
        httpServletResponse.setHeader("Pragma", "no-cache");
        httpServletResponse.setDateHeader("Expires", 0);
        httpServletResponse.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream =
                httpServletResponse.getOutputStream();
        responseOutputStream.write(captchaChallengeAsJpeg);
        responseOutputStream.flush();
        responseOutputStream.close();

  • To generate default Jcaptcha image you the following code

public class CaptchaServiceSingleton {
   
    private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService();
   
    public static ImageCaptchaService getInstance(){
        return instance;
    }
}

Verify your jcapthca string with sessionId,
  • verifyString is your String submitted throw the registration form or something else.
//String verifyString = request.getParameter("yourparam");
 String captchaId = request.getSession().getId();
   boolean isResponseCorrect =               CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId, verifyString);

  • You can change your Image by configuration as follows:

  1. Implement ListImageCaptchaEngine where you can change all your settings There are many generator classes for every class(for below of all generator)you can use any one of it.
    1. Word Generator
    2. Color Generator 
    3. Background Generator
    4. Font Generator 
 public class MyImageCaptchaEngine extends ListImageCaptchaEngine {
    @Override
    protected void buildInitialFactories() {
        WordGenerator wgen = new RandomWordGenerator("ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789");
        RandomRangeColorGenerator cgen = new RandomRangeColorGenerator(new int[] { 0, 255 }, new int[] { 20, 100 }, new int[] { 20, 100 });

        TextPaster textPaster = new RandomTextPaster(new Integer(4), new Integer(5), cgen, Boolean.TRUE);

        BackgroundGenerator backgroundGenerator = new UniColorBackgroundGenerator(new Integer(240), new Integer(50), new Color(252,252,253));
        Font[] fontsList = new Font[] { new Font("Helvetica", Font.TYPE1_FONT, 10), new Font("Arial", 0, 14), new Font("Vardana", 0, 17), };

        FontGenerator fontGenerator = new RandomFontGenerator(new Integer(18), new Integer(30), fontsList);
        WordToImage wordToImage = new ComposedWordToImage(fontGenerator, backgroundGenerator, textPaster);
        this.addFactory(new GimpyFactory(wgen, wordToImage));
    }
}
  •  change code as follows:

private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService(
            new FastHashMapCaptchaStore(),
            new MyImageCaptchaEngine(),
            180,
            100000,
            75000);

IF you are using open JDK replacing following two lines

  JPEGImageEncoder jpegEncoder =
                    JPEGCodec.createJPEGEncoder(jpegOutputStream);
  jpegEncoder.encode(challenge);   
        










replace with: 


ImageIO.write(challenge, "jpg", jpegOutputStream);
 

And that's it! 

2 comments: