SpringSecurity 图形验证码认证
卑微小钟 人气:0第一步:图形验证码接口
1.使用第三方的验证码生成工具Kaptcha
https://github.com/penggle/kaptcha
@Configuration public class KaptchaImageCodeConfig { @Bean public DefaultKaptcha getDefaultKaptcha(){ DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); Properties properties = new Properties(); properties.setProperty(Constants.KAPTCHA_BORDER, "yes"); properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "192,192,192"); properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "110"); properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "36"); properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "28"); properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "宋体"); properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); // 图片效果 properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); Config config = new Config(properties); defaultKaptcha.setConfig(config); return defaultKaptcha; } }
2.设置验证接口
Logger logger = LoggerFactory.getLogger(getClass()); public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; @GetMapping("/code/image") public void codeImage(HttpServletRequest request, HttpServletResponse response) throws IOException { // 获得随机验证码 String code = defaultKaptcha.createText(); logger.info("验证码:{}",code); // 将验证码存入session request.getSession().setAttribute(SESSION_KEY,code); // 绘制验证码 BufferedImage image = defaultKaptcha.createImage(code); // 输出验证码 ServletOutputStream out = response.getOutputStream(); ImageIO.write(image, "jpg", out); }
3.模板表单设置
<div class="form-group"> <label>验证码:</label> <input type="text" class="form-control" placeholder="验证码" name="code"> <img src="/code/image" th:src="@{/code/image}" onclick="this.src='/code/image?'+Math.random()"> </div>
第二步:设置图像验证过滤器
1.过滤器
@Component public class ImageCodeValidateFilter extends OncePerRequestFilter { private MyAuthenticationFailureHandler myAuthenticationFailureHandler; // 失败处理器 @Resource public void setMyAuthenticationFailureHandler(MyAuthenticationFailureHandler myAuthenticationFailureHandler) { this.myAuthenticationFailureHandler = myAuthenticationFailureHandler; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { try { if ("/login/form".equals(request.getRequestURI()) && request.getMethod().equalsIgnoreCase("post")) { // 获取session的验证码 String sessionCode = (String) request.getSession().getAttribute(PageController.SESSION_KEY); // 获取用户输入的验证码 String inputCode = request.getParameter("code"); // 判断是否正确 if(sessionCode == null||!sessionCode.equals(inputCode)){ throw new ValidateCodeException("验证码错误"); } } }catch (AuthenticationException e){ myAuthenticationFailureHandler.onAuthenticationFailure(request,response,e); //e.printStackTrace(); return; } filterChain.doFilter(request, response); } }
异常类
public class ValidateCodeException extends AuthenticationException { public ValidateCodeException(String msg) { super(msg); } }
注意:一定是继承AuthenticationException
第三步:将图像验证过滤器添加到springsecurity过滤器链中
1.添加到过滤器链中,并设置在用户认证过滤器(UsernamePasswordAuthenticationFilter)前
@Resource private ImageCodeValidateFilter imageCodeValidateFilter; @Override protected void configure(HttpSecurity http) throws Exception { // 前后代码略 // 添加图形验证码过滤器链 http.addFilterBefore(imageCodeValidateFilter, UsernamePasswordAuthenticationFilter.class) }
2.一定不要忘记放行验证码接口
// 拦截设置 http .authorizeHttpRequests() //排除/login .antMatchers("/login","/code/image").permitAll();
加载全部内容