Integrating Captcha in JSF 2.0

Generate own Captcha in JSF 2.0 and Richfaces.

captcha.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:a4j="http://richfaces.org/a4j">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>TODO supply a title</title>
    </head>
    <body>
        <h:form>
            <table border="0">
                <tr>
                    <td>
                        <h:graphicImage id="capimg" value="#{facesContext.externalContext.requestContextPath}/../Captcha.jpg"/>
                    </td>
                    <td>
                        <h:commandButton value="Change Image">
                            <a4j:support reRender="capimg" event="onclick"/>
                        </h:commandButton>
                    </td>
                </tr>
                <tr>
                    <td>
                        <h:inputText value="#{CaptchaAction.validate}"/>
                    </td>
                    <td>
                        <h:commandButton action="#{CaptchaAction.execute}" value="Click"/>
                    </td>
                </tr>
            </table>
        </h:form>
    </body>
</html>

Output :

web.xml

<servlet>
        <servlet-name>Captcha</servlet-name>
        <servlet-class>com.captcha.MyCaptcha</servlet-class>
        <init-param>
            <description>passing height</description>
            <param-name>height</param-name>
            <param-value>30</param-value>
        </init-param>
        <init-param>
            <description>passing height</description>
            <param-name>width</param-name>
            <param-value>120</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Captcha</servlet-name>
        <url-pattern>/Captcha.jpg</url-pattern>
    </servlet-mapping>

MyCaptcha.java (Servlet)

package com.captcha;

import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.awt.*;
import java.util.*;
import java.awt.font.TextAttribute;

public class MyCaptcha extends HttpServlet {

    private int height = 0;
    private int width = 0;
    public static final String CAPTCHA_KEY = "captcha_key_name";

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        height = Integer.parseInt(getServletConfig().getInitParameter("height"));
        width = Integer.parseInt(getServletConfig().getInitParameter("width"));
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response) throws IOException, ServletException {
        //Expire response
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Max-Age", 0);

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = image.createGraphics();
        Hashtable<TextAttribute, Object> map = new Hashtable<TextAttribute, Object>();
        Random r = new Random();
        String token = Long.toString(Math.abs(r.nextLong()), 36);
        String ch = token.substring(0, 6);
        Color c = new Color(0.6662f, 0.4569f, 0.3232f);
        GradientPaint gp = new GradientPaint(30, 30, c, 15, 25, Color.white, true);
        graphics2D.setPaint(gp);
        Font font = new Font("Verdana", Font.CENTER_BASELINE, 26);
        graphics2D.setFont(font);
        graphics2D.drawString(ch, 2, 20);
        graphics2D.dispose();

        HttpSession session = req.getSession(true);
        session.setAttribute(CAPTCHA_KEY, ch);

        OutputStream outputStream = response.getOutputStream();
        ImageIO.write(image, "jpeg", outputStream);
        outputStream.close();
    }
}

CaptchaAction.java(JSF Managed Bean)

package com.captcha;

import com.sun.facelets.FaceletContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

@ManagedBean(name = "CaptchaAction")
@ViewScoped
public class CaptchaAction {

    public CaptchaAction() {
    }
    String validate;

    public String getValidate() {
        return validate;
    }

    public void setValidate(String validate) {
        this.validate = validate;
    }

    public String execute() throws Exception {
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        Boolean isResponseCorrect = Boolean.FALSE;
        javax.servlet.http.HttpSession session = request.getSession();
        String parm = validate;
        String c = (String) session.getAttribute(MyCaptcha.CAPTCHA_KEY);
        if (parm.equals(c)) {
            return "success";
        } else {
            return "failed";
        }
    }
}
About these ads
This entry was posted in JSF 2.0 and tagged , , , . Bookmark the permalink.

11 Responses to Integrating Captcha in JSF 2.0

  1. vijay says:

    Eventhough a4j:support is used the page is getting refreshed. Rerender is not working.
    Unless the page is refreshed the the image is not changed. Please suggest us how we can do with ajax or a4j:support without refreshing the page.

    Please advice as early as possible

  2. mehmet says:

    thanks dude! you save my life!

  3. What i don’t realize is actually how you’re not actually a lot more smartly-appreciated
    than you might be now. You’re so intelligent. You know thus considerably relating to this subject, produced me individually consider it from so many various angles. Its like men and women don’t seem
    to be interested unless it’s one thing to do with Girl gaga! Your individual stuffs nice. At all times take care of it up!

  4. Pingback: kaptcha, JSF, RichFaces, captcha | Business World TI

  5. duke says:

    Thanks for the code. Saved me a lot of time. Using it with JSF2.0 (without RichFaces) and everything is working like charm. Thanks once again.

  6. Thanks, very helpful. I’ll prefer to change CaptchaAction to Validator:

    @FacesValidator
    public class CaptchaValidator implements Validator {

    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    String userInput = (String) value;
    String captcha = (String) Faces.getSession().getAttribute(MyCaptcha.CAPTCHA_KEY);

    if (userInput == null || captcha == null || !userInput.equals(captcha)) {
    FacesMessage message = new FacesMessage();
    message.setDetail(“Wrong captcha”);
    message.setSummary(“Wrong captcha”);
    message.setSeverity(FacesMessage.SEVERITY_ERROR);
    throw new ValidatorException(message);
    }
    }
    }

    Use of Omnifaces’s Faces.getSession() can be changed to context.getExternalContext().getSession(true)

    Add this to any form (in RichFaces 5 r:ajax instead of a4j:support):

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s