热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

SpringSecurity实现图形验证码功能的实例代码

SpringSecurity的前身是AcegiSecurity,是Spring项目组中用来提供安全认证服务的框架。这篇文章主要介绍了SpringSecurity实现图形验证码功能,需要的朋友可以参考下

Spring Security

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

Spring Security

下载:https://github.com/whyalwaysmea/Spring-Security

本文重点给大家介绍SpringSecurity实现图形验证码功能,具体内容如下:

1.开发生成图形验证码接口

-> 封装ImageCode对象,来存放图片验证码的内容、图片以及有效时间

public class ImageCode {
 private BufferedImage image;// 图片
 private String code;// 验证码
 private LocalDateTime expireTime;// 有效时间
 public ImageCode(BufferedImage image, String code, int expireIn) {
 this.image = image;
 this.code = code;
 // 出入一个秒数,自动转为时间,如过期时间为60s,这里的expireIn就是60,转换为当前时间上加上这个秒数
 this.expireTime = LocalDateTime.now().plusSeconds(expireIn);
 }
 public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) {
 this.image = image;
 this.code = code;
 this.expireTime = expireTime;
 }
 public BufferedImage getImage() {
 return image;
 }
 public void setImage(BufferedImage image) {
 this.image = image;
 }
 public String getCode() {
 return code;
 }
 public void setCode(String code) {
 this.code = code;
 }
 public LocalDateTime getExpireTime() {
 return expireTime;
 }
 public void setExpireTime(LocalDateTime expireTime) {
 this.expireTime = expireTime;
 }
}

-> 写一个Controller用于生成图片和校验验证码

public class ValidateCodeController {
 private static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";
 private SessionStrategy sessiOnStrategy= new HttpSessionSessionStrategy();
 @GetMapping("/code/image")
 public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
 // 根据随机数生成图片
 ImageCode imageCode = createImageCode(request);
 // 将随机数存到session中
 sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode);
 // 将生成的图片写到接口的响应中
 ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
 }

 private ImageCode createImageCode(HttpServletRequest request) {
 // 图片的宽高(像素)
 int width = 67;
 int height = 23;
 // 生成图片对象
 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 
 Graphics g = image.getGraphics();
 // 生成随机条纹干扰
 Random random = new Random();
 g.setColor(getRandColor(200, 250));
 g.fillRect(0, 0, width, height);
 g.setFont(new Font("Times New Roman", Font.ITALIC, 20));
 g.setColor(getRandColor(160, 200));
 for (int i = 0; i <155; i++) {
 int x = random.nextInt(width);
 int y = random.nextInt(height);
 int xl = random.nextInt(12);
 int yl = random.nextInt(12);
 g.drawLine(x, y, xl, yl);
 }
 
 // 生成四位随机数
 String sRand = "";
 for (int i = 0; i <4; i++) {
 String rand = String.valueOf(random.nextInt(10));
 sRand += rand;
 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
 g.drawString(rand, 13 * i + 6, 16);
 }
 g.dispose();
 // 60秒有效
 return new ImageCode(image, sRand, 60);
 }

 /**
 * 生成随机背景条纹
 * @param fc
 * @param bc
 * @return
 */
 private Color getRandColor(int fc, int bc) {
 Random random = new Random();
 if(fc > 255) {
 fc = 255;
 }
 if(bc > 255) {
 bc = 255;
 }
 int r = fc + random.nextInt(bc - fc);
 int g = fc + random.nextInt(bc - fc);
 int b = fc + random.nextInt(bc - fc);
 return new Color(r, g, b);
 }
}

第一步:根据随机数生成图片

ImageCode imageCode = createImageCode(request);

第二步:将随机数存到session中

sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode);

第三步:将生成的图片写到接口的响应中

ImageIO.write(imageCode.getImage(), “JPEG”, response.getOutputStream());

-> 在静态页面中加入图片验证码的标签


 图形验证码:
 
 
 
 

-> 将接口请求地址配进认证

@Override
protected void configure(HttpSecurity http) throws Exception {
 http.formLogin()
 .loginPage("/authencation/require")
 .loginProcessingUrl("/authentication/form")
 .successHandler(imoocAuthenticationSuccessHandler)
 .failureHandler(imoocAuthenticationFailureHandler)
 .and()
 .authorizeRequests()
 .antMatchers("/authencation/require", 
 securityPropertis.getBrowserPropertis().getLoginPage(),
 "/code/image").permitAll() // 加入"/code/image"地址
 .anyRequest()
 .authenticated()
 .and()
 .csrf().disable();
}

->启动服务器访问静态表单

如图所示:

图片验证码

2.在认证流程中加入图形验证码校验

-> 写一个filter进行拦截
public class ValidateCodeFilter extends OncePerRequestFilter{
 private AuthenticationFailureHandler authenticationFailureHandler;
 private SessionStrategy sessiOnStrategy= new HttpSessionSessionStrategy();
 @Override
 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
 throws ServletException, IOException {
 //如果访问的是/authentication/form并且为post请求
 if(StringUtils.equals("/authentication/form", request.getRequestURI())
 && StringUtils.equals(request.getMethod(), "post")) {
 try {
 // 验证图片验证码是否填写正确
 validate(new ServletWebRequest(request));
 } catch (ValidateCodeException e) {
 // 抛出异常,并返回,不再访问资源
 authenticationFailureHandler.onAuthenticationFailure(request, response, e);
 return;
 }
 }
 // 通过,执行后面的filter
 filterChain.doFilter(request, response);
 }
 // 校验验证码的逻辑
 private void validate(ServletWebRequest request) throws ServletRequestBindingException {
 ImageCode codeInSession = (ImageCode) sessionStrategy.getAttribute(request, ValidateCodeController.SESSION_KEY);
 String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), "imageCode");
 if(StringUtils.isBlank(codeInRequest)) {
 throw new ValidateCodeException("验证码的值不能为空");
 }
 if(codeInSession == null){
 throw new ValidateCodeException("验证码不存在");
 }
 if(codeInSession.isExpried()) {
 sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY);
 throw new ValidateCodeException("验证码已过期");
 }
 if(!StringUtils.equals(codeInSession.getCode(), codeInRequest)) {
 throw new ValidateCodeException("验证码不匹配");
 }
 sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY);
 }
 public AuthenticationFailureHandler getAuthenticationFailureHandler() {
 return authenticationFailureHandler;
 }
 public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
 this.authenticatiOnFailureHandler= authenticationFailureHandler;
 }
 public SessionStrategy getSessionStrategy() {
 return sessionStrategy;
 }
 public void setSessionStrategy(SessionStrategy sessionStrategy) {
 this.sessiOnStrategy= sessionStrategy;
 }
}

-> 配置再configure中,生效

@Override
protected void configure(HttpSecurity http) throws Exception {
 // 声明filter
 ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
 // 配置验证失败执行的handler
 validateCodeFilter.setAuthenticationFailureHandler(imoocAuthenticationFailureHandler);
 // 添加filter到认证流程
 http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
 .formLogin()
 .loginPage("/authencation/require")
 .loginProcessingUrl("/authentication/form")
 .successHandler(imoocAuthenticationSuccessHandler)
 .failureHandler(imoocAuthenticationFailureHandler)
 .and()
 .authorizeRequests()
 .antMatchers("/authencation/require", 
 securityPropertis.getBrowserPropertis().getLoginPage(),
 "/code/image").permitAll()
 .anyRequest()
 .authenticated()
 .and()
 .csrf().disable();
}

至此,图片验证码验证流程已经全部完成。

启动服务,进行测试即可。

总结

到此这篇关于SpringSecurity实现图形验证码功能的实例代码的文章就介绍到这了,更多相关SpringSecurity图形验证码内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 如何在任意浏览器中轻松安装并使用VSCode——Codeserver简易指南
    code-server 是一款强大的工具,允许用户在任何服务器上部署 VSCode,并通过浏览器进行访问和使用。这一解决方案不仅简化了开发环境的搭建过程,还提供了高度灵活的工作方式。用户只需访问 GitHub 上的官方仓库(GitHub-coder/code-server),即可获取详细的安装和配置指南,快速启动并运行 code-server。无论是个人开发者还是团队协作,code-server 都能提供高效、便捷的代码编辑体验。 ... [详细]
  • 本文深入解析了 Kubernetes 控制平面(特别是 API 服务器)与集群节点之间的通信机制,并对其通信路径进行了详细分类。旨在帮助用户更好地理解和定制其安装配置,从而增强网络安全性,确保集群的稳定运行。 ... [详细]
  • 提升 Kubernetes 集群管理效率的七大专业工具
    Kubernetes 在云原生环境中的应用日益广泛,然而集群管理的复杂性也随之增加。为了提高管理效率,本文推荐了七款专业工具,这些工具不仅能够简化日常操作,还能提升系统的稳定性和安全性。从自动化部署到监控和故障排查,这些工具覆盖了集群管理的各个方面,帮助管理员更好地应对挑战。 ... [详细]
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • 如何安装和使用 WinSCP 与 PuTTY:连接 Linux 系统的专业工具指南
    本指南详细介绍了如何在Windows环境中安装和使用WinSCP与PuTTY,以实现与Linux系统的安全连接。WinSCP是一款开源的图形化SFTP客户端,支持SSH和SCP协议,主要用于在本地和远程计算机之间安全地传输文件。用户可以通过官方下载页面获取最新版本的WinSCP和PuTTY,按照简单的步骤完成安装,并利用这些工具进行高效的文件管理和远程操作。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
  • 小程序的授权和登陆
    小程序的授权和登陆 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 本文介绍了如何在GitHub上设置多个SSH Key,以解决原有Key失效的问题,并确保不同项目使用不同的私钥进行安全访问。 ... [详细]
  • 大家好,我是李白。本文将分享一个从零开始的全栈项目,涵盖了设计、前端、后端和服务端的全面学习过程。通过这个项目,我希望能够帮助初学者更好地理解和掌握全栈开发的技术栈。 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
author-avatar
x-诗儿_683
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有