- 修改CustomAuthenticationFailureHandler类和CustomAuthenticationSuccessHandler
| # 将实现接口AuthenticationSuccessHandler修改为SavedRequestAwareAuthenticationSuccessHandler |
| @Component("customAuthenticationSuccessHandler") |
| public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { |
| Logger logger = LoggerFactory.getLogger(getClass()); |
| @Override |
| public void onAuthenticationSuccess(HttpServletRequest request, |
| HttpServletResponse response, Authentication authentication) throws IOException, ServletException { |
| System.out.println("CustomAuthenticationSuccessHandler ---> 认证成功"); |
| } |
| } |
| |
| @Component("customAuthenticationFailureHandler") |
| public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { |
| @Override |
| public void onAuthenticationFailure(HttpServletRequest request, |
| HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { |
| System.out.println("CustomAuthenticationFailureHandler ---> 认证失败"); |
| } |
| } |
| # core模块导入依赖 |
| <dependency> |
| <groupId>com.github.penggle</groupId> |
| <artifactId>kaptcha</artifactId> |
| </dependency> |
| |
| # core模块编写配置类KaptchaImageCodeConfig |
| @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; |
| } |
| } |
| |
| # 编写CustomLoginController获取验证码 |
| @Controller |
| public class CustomLoginController { |
| Logger logger = LoggerFactory.getLogger(getClass()); |
| public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; |
| @Autowired |
| private DefaultKaptcha defaultKaptcha; |
| |
| @RequestMapping("/code/image") |
| public void imageCode(HttpServletRequest request, HttpServletResponse response) throws IOException { |
| |
| String code = defaultKaptcha.createText(); |
| logger.info("生成的图形验证码是:" + code); |
| |
| request.getSession().setAttribute(SESSION_KEY , code); |
| |
| BufferedImage image = defaultKaptcha.createImage(code); |
| |
| ServletOutputStream out = response.getOutputStream(); |
| ImageIO.write(image, "jpg", out); |
| } |
| } |
| |
| # 前端获取发送请求获取 |
| GET http: |
| |
| # core模块的SpringSecurityConfig中放行获取图形验证码的接口 |
| # code模块编写ImageCodeValidateFilter、ValidateCodeException |
| @Component("imageCodeValidateFilter") |
| public class ImageCodeValidateFilter extends OncePerRequestFilter { |
| |
| Logger logger = LoggerFactory.getLogger(getClass()); |
| |
| @Autowired |
| CustomAuthenticationFailureHandler customAuthenticationFailureHandler; |
| |
| @Override |
| protected void doFilterInternal(HttpServletRequest request, |
| HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { |
| String sessionCode = |
| (String)request.getSession().getAttribute(CustomLoginController.SESSION_KEY); |
| |
| String inpuCode = request.getParameter("code"); |
| logger.info("session中的验证码为:" + sessionCode); |
| logger.info("登录时输入的验证码为:" + inpuCode); |
| |
| String loginUrl = "/login"; |
| |
| if(loginUrl.equals(request.getRequestURI()) |
| && request.getMethod().equalsIgnoreCase("post")) { |
| try { |
| |
| validate(request); |
| }catch (AuthenticationException e) { |
| |
| customAuthenticationFailureHandler.onAuthenticationFailure(request, response, e); |
| |
| return; |
| } |
| } |
| |
| filterChain.doFilter(request, response); |
| } |
| |
| private void validate(HttpServletRequest request) { |
| |
| String sessionCode = |
| (String)request.getSession().getAttribute(CustomLoginController.SESSION_KEY); |
| |
| String inpuCode = request.getParameter("code"); |
| logger.info("session中的验证码为:" + sessionCode); |
| logger.info("登录时输入的验证码为:" + inpuCode); |
| |
| if(StringUtils.isBlank(inpuCode)) { |
| throw new ValidateCodeException("验证码不能为空"); |
| } |
| if(!inpuCode.equalsIgnoreCase(sessionCode)) { |
| throw new ValidateCodeException("验证码输入错误"); |
| } |
| } |
| |
| } |
| |
| # code模块的SpringSecurityConfig中添加如下:注入过滤器,并添加到UsernamePasswordAuthenticationFilter过滤器前 |
| @Autowired |
| private ImageCodeValidateFilter imageCodeValidateFilter; |
| |
| .addFilterBefore(imageCodeValidateFilter, UsernamePasswordAuthenticationFilter.class) |
| |
| # 测试:使用用户名 + 密码 + 图形验证码进行认证 |
| POST http: |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术