Reputation: 189
I need to integrate kaptcha in java spring, on the official website https://code.google.com/p/kaptcha/wiki/SpringUsage is very old information.
Upvotes: 0
Views: 3952
Reputation: 364
There is an open source Spring Boot starter project witch will validate reCAPTCHA for you.
You just have to set the desired URLs (which you want to protect with captcha, e.g.: /api/sign-up) in your config file and this library will check whether the user sent a valid captcha response.
More on GitHub: https://github.com/Mr-DeWitt/spring-boot-recaptcha
Upvotes: 0
Reputation: 111
Add the maven dependency:
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
Add the kaptcha configurations to the application.properties:
#Kaptcha
kaptcha.config.imageWidth=310
kaptcha.config.imageHeight=55
kaptcha.config.textProducerCharString=0123456789aAbBcCdDEeFeGgHhIi
kaptcha.config.textProducerCharLength=6
kaptcha.config.headerName=KAPTCHA_HEADER
kaptcha.config.useBorder=no
kaptcha.config.textColor=48,101,137
Pickup the configurations using @ConfigurationProperties
@Data
@Component
@ConfigurationProperties(prefix="kaptcha.config")
public class KaptchaConfigurations{
private String imageWidth;
private String imageHeight;
private String textProducerCharString;
private String textProducerCharLength;
private String headerName;
private String useBorder;
private String backgroundClass;
private String textColor;
}
*if you are not using lombok replace @Data with getters and setters.
Declare Producer @Bean:
@Bean
public Producer createKaptchaProducer(KaptchaConfigurations
kaptchaConfigurations) {
DefaultKaptcha kaptcha = new DefaultKaptcha();
Properties properties = new Properties();
properties.put(Constants.KAPTCHA_IMAGE_HEIGHT ,
kaptchaConfigurations.getImageHeight());
properties.put(Constants.KAPTCHA_IMAGE_WIDTH,
kaptchaConfigurations.getImageWidth());
properties.put(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH ,
kaptchaConfigurations.getTextProducerCharLength());
properties.put(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING,
kaptchaConfigurations.getTextProducerCharString());
properties.put(Constants.KAPTCHA_BORDER,
kaptchaConfigurations.getUseBorder());
properties.put(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR,
kaptchaConfigurations.getTextColor());
properties.put(Constants.KAPTCHA_NOISE_COLOR,
kaptchaConfigurations.getTextColor());
kaptcha.setConfig(new Config(properties));
return kaptcha;
}
Create an endpoint to get the generated captcha and save the captcha text in the session:
@GetMapping("/image")
public void handleRequest(
HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control",
"no-store, no-cache, must- revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
String capText = captchaProducer.createText();
request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY,
capText);
// create the image with the text
BufferedImage bi = captchaProducer.createImage(capText);
ServletOutputStream out = response.getOutputStream();
// write the data out
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
}
Create an aspect to validate the captcha:
@Aspect
@Component
public class KaptchaAspect {
private KaptchaConfigurations kaptchaConfigurations;
public KaptchaAspect(KaptchaConfigurations kaptchaConfigurations) {
this.kaptchaConfigurations = kaptchaConfigurations;
}
@Before("@annotation(ValidateKaptcha)")
public void validateKaptcha() throws Throwable {
String headerName = this.kaptchaConfigurations.getHeaderName();
HttpServletRequest request =
((ServletRequestAttributes)
RequestContextHolder
.currentRequestAttributes())
.getRequest();
String headerValue = request.getHeader(headerName);
String kaptchaSessionValue =
request.getSession()
.getAttribute(Constants.KAPTCHA_SESSION_KEY)
.toString();
if(headerValue == null || kaptchaSessionValue == null) {
throw new BusinessException();
}
if(!headerValue.equals(kaptchaSessionValue)) {
throw new BusinessException();
}
}
}
Declare the validation annotation:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateKaptcha {
}
Use the @ValidateKaptcha on top of any endpoint needs to validate the captcha:
@ValidateKaptcha
@PostMapping("/forgot-password-by-user-name")
public ResponseEntity<?> forgotPasswordByUsername(@RequestBody @Valid
ForgotPasswordByUsernameInput forgotPasswordByUsernameInput) {
...
}
From the client side pass the kaptcha value in the header, name it KAPTCHA_HEADER.
Upvotes: 2
Reputation: 2817
You can use reCAPTCHA , follow this tutorial it will help you reCAPTCHA link
Upvotes: 1