##图片验证码之kaptcha
1、首先先初始化图片验证码
public class VerifyServlet extends HttpServlet {
private static final long serialVersionUID = -5051097528828603895L;
private DefaultKaptcha dk;
/**
* 初始化验证图片属性
*/
@Override
public void init() throws ServletException {
dk = new DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "yes");
// 边框颜色
properties.setProperty("kaptcha.border.color", "105,179,90");
// 字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "red");
// 图片宽
properties.setProperty("kaptcha.image.width", "110");
// 图片高
properties.setProperty("kaptcha.image.height", "40");
// 字体大小
properties.setProperty("kaptcha.textproducer.font.size", "30");
// session key
properties.setProperty("kaptcha.session.key", "code");
// 验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
// 字体
properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
Config config = new Config(properties);
dk.setConfig(config);
}
/**
* @param request
* @param response
* @throws ServletException
* @throws java.io.IOException
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {
byte[] captcha = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
// 将生成的验证码保存在session中
String createText = dk.createText();
HttpSession session = request.getSession();
session.setAttribute("validateCode", createText);
BufferedImage bi = dk.createImage(createText);
ImageIO.write(bi, "jpg", out);
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
captcha = out.toByteArray();
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
ServletOutputStream sout = response.getOutputStream();
sout.write(captcha);
sout.flush();
sout.close();
}
2、其次将初始化图片验证码类配置bean(在启动类加以下代码)
/**
* 注入验证码servlet,和对应的链接绑定
*/
@Bean
public ServletRegistrationBean indexServletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(new VerifyServlet());
registration.addUrlMappings(“/code/getVerifyCode”);
return registration;
}
3、验证码登陆过滤器
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {
private static final PathMatcher pathMatcher = new AntPathMatcher();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("这是验证码的过滤器");
if(isProtectedUrl(request)) {
String verifyCode = request.getParameter(SecurityConstants.VALIDATE_CODE_PARAMETER);
if(!validateVerify(verifyCode)) {
//手动设置异常
request.getSession().setAttribute("verifyCode",new DisabledException("验证码输入错误"));
// 转发到错误Url
request.getRequestDispatcher(“/error”).forward(request,response);
} else {
filterChain.doFilter(request,response);
}
} else {
filterChain.doFilter(request,response);
}
}
private boolean validateVerify(String inputVerify) {
//获取当前线程绑定的request对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 不分区大小写
// 这个validateCode是在servlet中存入session的名字
String validateCode = ((String) request.getSession().getAttribute("validateCode")).toLowerCase();
inputVerify = inputVerify.toLowerCase();
// log.info("验证码:{}, 用户输入:{}", validateCode, inputVerify);
return validateCode.equals(inputVerify);
}
/**
* 拦截登陆请求
*/
private boolean isProtectedUrl(HttpServletRequest request) {
return "POST".equals(request.getMethod()) &&
pathMatcher.match(SecurityConstants.LOGIN_PROCESSING_URL_FORM, request.getServletPath());
}
4、过滤器注入
@Component
public class ValidateCodeSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
@Autowired
private ValidateCodeFilter validateCodeFilter;
@Override
public void configure(HttpSecurity http) throws Exception {
// 注入过滤器
http.addFilterBefore(validateCodeFilter, AbstractPreAuthenticatedProcessingFilter.class);
}
}