Spring Security登录添加验证码的实现过程
登录添加验证码是一个非常常见的需求,网上也有非常成熟的解决方案,其实,要是自己自定义登录实现这个并不难,但是如果需要在SpringSecurity框架中实现这个功能,还得稍费一点功夫,本文就和小伙伴来分享下在SpringSecurity框架中如何添加验证码。
关于SpringSecurity基本配置,这里就不再多说,小伙伴有不懂的可以参考我的书《SpringBoot+Vue全栈开发实战》,本文主要来看如何加入验证码功能。
准备验证码
要有验证码,首先得先准备好验证码,本文采用Java自画的验证码,代码如下:
/** *生成验证码的工具类 */ publicclassVerifyCode{ privateintwidth=100;//生成验证码图片的宽度 privateintheight=50;//生成验证码图片的高度 privateString[]fontNames={"宋体","楷体","隶书","微软雅黑"}; privateColorbgColor=newColor(255,255,255);//定义验证码图片的背景颜色为白色 privateRandomrandom=newRandom(); privateStringcodes="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; privateStringtext;//记录随机字符串 /** *获取一个随意颜色 * *@return */ privateColorrandomColor(){ intred=random.nextInt(150); intgreen=random.nextInt(150); intblue=random.nextInt(150); returnnewColor(red,green,blue); } /** *获取一个随机字体 * *@return */ privateFontrandomFont(){ Stringname=fontNames[random.nextInt(fontNames.length)]; intstyle=random.nextInt(4); intsize=random.nextInt(5)+24; returnnewFont(name,style,size); } /** *获取一个随机字符 * *@return */ privatecharrandomChar(){ returncodes.charAt(random.nextInt(codes.length())); } /** *创建一个空白的BufferedImage对象 * *@return */ privateBufferedImagecreateImage(){ BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2Dg2=(Graphics2D)image.getGraphics(); g2.setColor(bgColor);//设置验证码图片的背景颜色 g2.fillRect(0,0,width,height); returnimage; } publicBufferedImagegetImage(){ BufferedImageimage=createImage(); Graphics2Dg2=(Graphics2D)image.getGraphics(); StringBuffersb=newStringBuffer(); for(inti=0;i<4;i++){ Strings=randomChar()+""; sb.append(s); g2.setColor(randomColor()); g2.setFont(randomFont()); floatx=i*width*1.0f/4; g2.drawString(s,x,height-15); } this.text=sb.toString(); drawLine(image); returnimage; } /** *绘制干扰线 * *@paramimage */ privatevoiddrawLine(BufferedImageimage){ Graphics2Dg2=(Graphics2D)image.getGraphics(); intnum=5; for(inti=0;i这个工具类很常见,网上也有很多,就是画一个简单的验证码,通过流将验证码写到前端页面,提供验证码的Controller如下:
@RestController publicclassVerifyCodeController{ @GetMapping("http://www.haoziyuan.cc/vercode") publicvoidcode(HttpServletRequestreq,HttpServletResponseresp)throwsIOException{ VerifyCodevc=newVerifyCode(); BufferedImageimage=vc.getImage(); Stringtext=vc.getText(); HttpSessionsession=req.getSession(); session.setAttribute("index_code",text); VerifyCode.output(image,resp.getOutputStream()); } }这里创建了一个VerifyCode对象,将生成的验证码字符保存到session中,然后通过流将图片写到前端,img标签如下:
展示效果如下:
自定义过滤器
在登陆页展示验证码这个就不需要我多说了,接下来我们来看看如何自定义验证码处理器:
@Component publicclassVerifyCodeFilterextendsGenericFilterBean{ privateStringdefaultFilterProcessUrl="/doLogin"; @Override publicvoiddoFilter(ServletRequestreq,ServletResponseres,FilterChainchain) throwsIOException,ServletException{ HttpServletRequestrequest=(HttpServletRequest)req; HttpServletResponseresponse=(HttpServletResponse)res; if("POST".equalsIgnoreCase(request.getMethod())&&defaultFilterProcessUrl.equals(request.getServletPath())){ //验证码验证 StringrequestCaptcha=request.getParameter("code"); StringgenCaptcha=(String)request.getSession().getAttribute("index_code"); if(StringUtils.isEmpty(requestCaptcha)) thrownewAuthenticationServiceException("验证码不能为空!"); if(!genCaptcha.toLowerCase().equals(requestCaptcha.toLowerCase())){ thrownewAuthenticationServiceException("验证码错误!"); } } chain.doFilter(request,response); } }自定义过滤器继承自GenericFilterBean,并实现其中的doFilter方法,在doFilter方法中,当请求方法是POST,并且请求地址是/doLogin时,获取参数中的code字段值,该字段保存了用户从前端页面传来的验证码,然后获取session中保存的验证码,如果用户没有传来验证码,则抛出验证码不能为空异常,如果用户传入了验证码,则判断验证码是否正确,如果不正确则抛出异常,否则执行chain.doFilter(request,response);使请求继续向下走。
配置
最后在SpringSecurity的配置中,配置过滤器,如下:
@Configuration publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{ @Autowired VerifyCodeFilterverifyCodeFilter; ... ... @Override protectedvoidconfigure(HttpSecurityhttp)throwsException{ http.addFilterBefore(verifyCodeFilter,UsernamePasswordAuthenticationFilter.class); http.authorizeRequests() .antMatchers("/admin/**").hasRole("admin") ... ... .permitAll() .and() .csrf().disable(); } }这里只贴出了部分核心代码,即http.addFilterBefore(verifyCodeFilter,UsernamePasswordAuthenticationFilter.class);,如此之后,整个配置就算完成了。
接下来在登录中,就需要传入验证码了,如果不传或者传错,都会抛出异常,例如不传的话,抛出如下异常:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。