如何用SpringSecurity自定义验证码?
导入依赖
- 这里使用Google的验证码
- 因为Google官方的maven坐标导入不了,使用的是镜像
com.github.penggle
kaptcha
2.3.2
设置图片验证码路径
- 谷歌提供了一个默认的Servletcom.google.code.kaptcha.servlet.KaptchaServlet
- 设置路径
@Configuration
public class ServletConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
KaptchaServlet kaptchaServlet = new KaptchaServlet();
return new ServletRegistrationBean<>(kaptchaServlet,"/captcha.jpg");
}
}
自定义filter
@Component
public class CheckCaptchaFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String realRequestUrl = request.getRequestURI().substring(request.getContextPath().length());
// 不是登录请求,放行
if (!"/login".equals(realRequestUrl)) {
filterChain.doFilter(request,response);
return;
}
// 获取 captcha
String sessionCaptcha = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
String captcha = request.getParameter("captcha");
if(sessionCaptcha.equals(captcha)) {
// 验证码正确,清除验证码session
request.getSession().removeAttribute(Constants.KAPTCHA_SESSION_KEY);
filterChain.doFilter(request,response);
} else {
// throw new RuntimeException("验证码错误");
response.sendRedirect(request.getContextPath() + "/login.html");
}
}
}
Filter添加
- 把自定义的filter添加到Security的过滤器链中
- 应当在身份验证过滤器之前UsernamePasswordAuthenticationFilter
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CheckCaptchaFilter checkCaptchaFilter;
// 省略.....
@Override
protected void configure(HttpSecurity http) throws Exception {
// 省略.....
http.addFilterBefore(checkCaptchaFilter, UsernamePasswordAuthenticationFilter.class);
}
}