Implementación de CAPTCHA con Google Kaptcha en aplicaciones Java

Para integrar la generación de CAPTCHAs gráficos en un poryecto Java, se puede utilizar la biblioteca Google Kaptcha. La configuración se realiza mediante un archivo de propiedades que controla aspectos visuales como bordes, colores, fuentes y efectos de distorsión.

Primero, se agrega la dependencia correspondiente en el archivo pom.xml:

<dependency>
    <groupId>com.google.code.kaptcha</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

El corazón de la configuración reside en la clase Config, que interpreta las propiedades y define los productores de imagen, texto y efectos. A continuación se muestra una versión reestructurada de sus métodos principales:

import java.awt.Color;
import java.awt.Font;
import java.util.Properties;

public class CaptchaConfig {
    private Properties props;
    private ConfigHelper configHelper;

    public CaptchaConfig(Properties inputProps) {
        this.props = inputProps;
        this.configHelper = new ConfigHelper();
    }

    public boolean hasBorder() {
        String key = "kaptcha.border";
        return configHelper.getBoolean(key, props.getProperty(key), true);
    }

    public Color borderColor() {
        String key = "kaptcha.border.color";
        return configHelper.getColor(key, props.getProperty(key), Color.BLACK);
    }

    public int borderWidth() {
        String key = "kaptcha.border.thickness";
        return configHelper.getPositiveInt(key, props.getProperty(key), 1);
    }

    public char[] allowedCharacters() {
        String key = "kaptcha.textproducer.char.string";
        return configHelper.getChars(key, props.getProperty(key), "abcdefhkmnprstwxy2345678".toCharArray());
    }

    public int textLength() {
        String key = "kaptcha.textproducer.char.length";
        return configHelper.getPositiveInt(key, props.getProperty(key), 5);
    }

    public int fontSize() {
        String key = "kaptcha.textproducer.font.size";
        return configHelper.getPositiveInt(key, props.getProperty(key), 40);
    }

    public Color textColor() {
        String key = "kaptcha.textproducer.font.color";
        return configHelper.getColor(key, props.getProperty(key), Color.BLACK);
    }

    public Color noiseColor() {
        String key = "kaptcha.noise.color";
        return configHelper.getColor(key, props.getProperty(key), Color.BLACK);
    }

    public int imageWidth() {
        String key = "kaptcha.image.width";
        return configHelper.getPositiveInt(key, props.getProperty(key), 200);
    }

    public int imageHeight() {
        String key = "kaptcha.image.height";
        return configHelper.getPositiveInt(key, props.getProperty(key), 50);
    }

    public Producer imageProducer() {
        String key = "kaptcha.producer.impl";
        return (Producer) configHelper.getClassInstance(key, props.getProperty(key), new DefaultKaptcha(), this);
    }
}

En un entorno Spring Boot, la configuración se define como un bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;

@Configuration
public class CaptchaAutoConfig {

    @Bean
    public Producer captchaProducer() {
        Properties settings = new Properties();
        settings.put("kaptcha.border", "no");
        settings.put("kaptcha.textproducer.char.length", "4");
        settings.put("kaptcha.image.width", "150");
        settings.put("kaptcha.image.height", "50");
        settings.put("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy");
        settings.put("kaptcha.textproducer.font.color", "black");
        settings.put("kaptcha.textproducer.font.size", "40");
        settings.put("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
        settings.put("kaptcha.textproducer.char.string", "acdefhkmnprtwxy2345678");

        CaptchaConfig config = new CaptchaConfig(settings);
        return config.imageProducer();
    }
}

Para generar y servir la imagen del CAPTCHA, se implementa un controlador que crea el texto, lo almacena en la sesión HTTP y escribe la imagen resultante en la respuesta:

import javax.imageio.ImageIO;
import javax.servlet.http.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class CaptchaController {

    private final Producer captchaGenerator;

    public CaptchaController(Producer generator) {
        this.captchaGenerator = generator;
    }

    @GetMapping("/captcha-image")
    public void serveCaptcha(HttpServletRequest req, HttpServletResponse res) throws IOException {
        HttpSession session = req.getSession();
        String captchaText = captchaGenerator.createText();
        session.setAttribute("GENERATED_CAPTCHA", captchaText);

        BufferedImage captchaImage = captchaGenerator.createImage(captchaText);
        
        res.setContentType("image/jpeg");
        res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        res.setHeader("Pragma", "no-cache");
        res.setDateHeader("Expires", 0);

        ImageIO.write(captchaImage, "jpg", res.getOutputStream());
    }
}

Etiquetas: google-kaptcha java-captcha spring-boot-integration Web-Security image-generation

Publicado el 7-16 07:21