编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

在spring Security 中集成kaptcha图片验证码登陆

wxchong 2024-06-30 10:48:36 开源技术 13 ℃ 0 评论

kaptcha图片验证码,可以让开发的系统更加安全,相比于其他的验证方式,kaptcha验证能快速集成,并开发方便,这里就介绍下,如何简单,快速的与spring security进行集成:

  1. 添加maven依赖:

<dependency>

<groupId>com.github.penggle</groupId>

<artifactId>kaptcha</artifactId>

<version>2.3.2</version>

</dependency>

  1. 增加kaptcha配置到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
  1. 定义配置文件,使用 @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;
}
  1. 定义 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;
}
  1. 创建生成captcha 图片的方法,并保存到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();
}
}
  1. 创建一个切面来验证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();
       }
    }
}
  1. 定义验证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 {
}


8. 在需要进行验证的接口上使用 @ValidateKaptcha

@ValidateKaptcha
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody @Valid 
      User user) { 
 ...
}


这样,我们可以在前端页面使用地址 /image 来获取包含验证码的图片,然后提交页面到/login, 系统就会验证,图片验证码。


Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表