这篇文章主要介绍了Spring Security实现验证码登录功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
在spring security实现登录注销功能的基础上进行开发。
1、添加生成验证码的控制器。
(1)、生成验证码
/** * 引入 Security 配置属性类 */ @Autowired private SecurityProperties securityProperties; @Override public ImageCode createCode(HttpServletRequest request ) { //如果请求中有 width 参数,则用请求中的,否则用 配置属性中的 int width = ServletRequestUtils.getIntParameter(request,"width",securityProperties.getWidth()); //高度(宽度) int height = ServletRequestUtils.getIntParameter(request,"height",securityProperties.getHeight()); //图片验证码字符个数 int length = securityProperties.getLength(); //过期时间 int expireIn = securityProperties.getExpireIn(); 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, x + xl, y + yl); } String sRand = ""; for (int i = 0; i < length; 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(); return new ImageCode(image, sRand, expireIn); } /** * 生成随机背景条纹 */ 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); }
(2)、验证码控制器
public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; @Autowired private ValidateCodeGenerator imageCodeGenerator; /** * Session 对象 */ private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); @GetMapping("/code/image") public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException { ImageCode imageCode = imageCodeGenerator.createCode(request); //将随机数 放到Session中 sessionStrategy.setAttribute(new ServletWebRequest(request),SESSION_KEY,imageCode); request.getSession().setAttribute(SESSION_KEY,imageCode); //写给response 响应 response.setHeader("Cache-Control", "no-store, no-cache"); response.setContentType("image/jpeg"); ImageIO.write(imageCode.getImage(),"JPEG",response.getOutputStream()); }
(3)、其它辅助类
@Data public class ImageCode { /** * 图片 */ private BufferedImage image; /** * 随机数 */ private String code; /** * 过期时间 */ private LocalDateTime expireTime; public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) { this.image = image; this.code = code; this.expireTime = expireTime; } public ImageCode(BufferedImage image, String code, int expireIn) { this.image = image; this.code = code; //当前时间 加上 设置过期的时间 this.expireTime = LocalDateTime.now().plusSeconds(expireIn); } public boolean isExpried(){ //如果 过期时间 在 当前日期 之前,则验证码过期 return LocalDateTime.now().isAfter(expireTime); } }
@ConfigurationProperties(prefix = "sso.security.code.image") @Component @Data public class SecurityProperties { /** * 验证码宽度 */ private int width = 67; /** * 高度 */ private int height = 23; /** * 长度(几个数字) */ private int length = 4; /** * 过期时间 */ private int expireIn = 60; /** * 需要图形验证码的 url */ private String url; }
(4)、验证
2、添加html" target="_blank">过滤器,进行验证码验证
@Component @Slf4j public class ValidateCodeFilter extends OncePerRequestFilter implements InitializingBean { /** * 登录失败处理器 */ @Autowired private AuthenticationFailureHandler failureHandler; /** * Session 对象 */ private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); /** * 创建一个Set 集合 存放 需要验证码的 urls */ private Set<String> urls = new HashSet<>(); /** * spring的一个工具类:用来判断 两字符串 是否匹配 */ private AntPathMatcher pathMatcher = new AntPathMatcher(); @Autowired private SecurityProperties securityProperties; /** * 这个方法是 InitializingBean 接口下的一个方法, 在初始化配置完成后 运行此方法 */ @Override public void afterPropertiesSet() throws ServletException { super.afterPropertiesSet(); //将 application 配置中的 url 属性进行 切割 String[] configUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens(securityProperties.getUrl(), ","); //添加到 Set 集合里 urls.addAll(Arrays.asList(configUrls)); //因为登录请求一定要有验证码 ,所以直接 add 到set 集合中 urls.add("/authentication/form"); } @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { boolean action = false; for (String url:urls){ //如果请求的url 和 配置中的url 相匹配 if (pathMatcher.match(url,httpServletRequest.getRequestURI())){ action = true; } } //拦截请求 if (action){ logger.info("拦截成功"+httpServletRequest.getRequestURI()); //如果是登录请求 try { validate(new ServletWebRequest(httpServletRequest)); }catch (ValidateCodeException exception){ //返回错误信息给 失败处理器 failureHandler.onAuthenticationFailure(httpServletRequest,httpServletResponse,exception); return; } } filterChain.doFilter(httpServletRequest,httpServletResponse); } private void validate(ServletWebRequest request) throws ServletRequestBindingException { //从session中取出 验证码 ImageCode codeInSession = (ImageCode) sessionStrategy.getAttribute(request,ValidateCodeController.SESSION_KEY); //从request 请求中 取出 验证码 String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(),"imageCode"); if (StringUtils.isBlank(codeInRequest)){ logger.info("验证码不能为空"); throw new ValidateCodeException("验证码不能为空"); } if (codeInSession == null){ logger.info("验证码不存在"); throw new ValidateCodeException("验证码不存在"); } if (codeInSession.isExpried()){ logger.info("验证码已过期"); sessionStrategy.removeAttribute(request,ValidateCodeController.SESSION_KEY); throw new ValidateCodeException("验证码已过期"); } if (!StringUtils.equals(codeInSession.getCode(),codeInRequest)){ logger.info("验证码不匹配"+"codeInSession:"+codeInSession.getCode() +", codeInRequest:"+codeInRequest); throw new ValidateCodeException("验证码不匹配"); } //把对应 的 session信息 删掉 sessionStrategy.removeAttribute(request,ValidateCodeController.SESSION_KEY); }
3、在核心配置BrowserSecurityConfig中添加过滤器配置
@Autowired private ValidateCodeFilter validateCodeFilter; @Override protected void configure(HttpSecurity http) throws Exception { //在UsernamePasswordAuthenticationFilter 过滤器前 加一个过滤器 来搞验证码 http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) //表单登录 方式 .formLogin() .loginPage("/authentication/require") //登录需要经过的url请求 .loginProcessingUrl("/authentication/form") .passwordParameter("pwd") .usernameParameter("user") .successHandler(mySuccessHandler) .failureHandler(myFailHandler) .and() //请求授权 .authorizeRequests() //不需要权限认证的url .antMatchers("/authentication/*","/code/image").permitAll() //任何请求 .anyRequest() //需要身份认证 .authenticated() .and() //关闭跨站请求防护 .csrf().disable(); //默认注销地址:/logout http.logout(). //注销之后 跳转的页面 logoutSuccessUrl("/authentication/require"); }
4、异常辅助类
public class ValidateCodeException extends AuthenticationException { public ValidateCodeException(String msg, Throwable t) { super(msg, t); } public ValidateCodeException(String msg) { super(msg); } }
5、测试
(1)、不输入验证码
(2)、添加验证码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍Springboot实现验证码登录,包括了Springboot实现验证码登录的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Springboot实现验证码登录的具体代码,供大家参考,具体内容如下 因为在项目中需要使用到验证码,我总结一下在项目中如何快速解决项目需求~验证码,下面推荐给大家速上手验证码的例子。 一、编写验证码工具类 二、controller层使用 验证用户
本文向大家介绍java实现登录验证码,包括了java实现登录验证码的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java实现登录验证码的具体代码,供大家参考,具体内容如下 1、ValidateCode.java 2、Controller 3、html 效果图 更多关于验证码的文章请点击查看: 《java验证码》 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐
本文向大家介绍springmvc下实现登录验证码功能示例,包括了springmvc下实现登录验证码功能示例的使用技巧和注意事项,需要的朋友参考一下 总体思路,简单讲,就是后台生成图片同时将图片信息保存在session,前端显示图片,输入验证码信息后提交表单到后台,取出存放在session里的验证码信息,与表单提交的验证码信息核对。 点击验证码图片时,通过jquery重新请求后台生成验证码图片方法,
本文向大家介绍JavaScript登录验证码的实现,包括了JavaScript登录验证码的实现的使用技巧和注意事项,需要的朋友参考一下 废话不多说,实现js登录验证码的功能需要下面两步,具体实现过程如下所示: 1.js 2.html 以上所述是小编给大家介绍的JavaScript登录验证码的实现,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对呐喊教程网
本文向大家介绍SpringBoot 配合 SpringSecurity 实现自动登录功能的代码,包括了SpringBoot 配合 SpringSecurity 实现自动登录功能的代码的使用技巧和注意事项,需要的朋友参考一下 自动登录是我们在软件开发时一个非常常见的功能,例如我们登录 QQ 邮箱: 很多网站我们在登录的时候都会看到类似的选项,毕竟总让用户输入用户名密码是一件很麻烦的事。 自动登录功能
本文向大家介绍Django框架登录加上验证码校验实现验证功能示例,包括了Django框架登录加上验证码校验实现验证功能示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Django框架登录加上验证码校验实现验证功能。分享给大家供大家参考,具体如下: 验证码生成函数 login.html html文件加上<img src="/verify_code" alt="">…当然这里还需要配置ur