SpringSecurity中怎么实现验证码登录功能,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
网站建设哪家好,找创新互联公司!专注于网页设计、网站建设、微信开发、小程序设计、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了同江免费建站欢迎大家使用!
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)、其它辅助类
@Datapublic 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@Datapublic class SecurityProperties { /** * 验证码宽度 */ private int width = 67; /** * 高度 */ private int height = 23; /** * 长度(几个数字) */ private int length = 4; /** * 过期时间 */ private int expireIn = 60; /** * 需要图形验证码的 url */ private String url;}
(4)、验证
2、添加过滤器,进行验证码验证
@Component@Slf4jpublic class ValidateCodeFilter extends OncePerRequestFilter implements InitializingBean { /** * 登录失败处理器 */ @Autowired private AuthenticationFailureHandler failureHandler; /** * Session 对象 */ private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); /** * 创建一个Set 集合 存放 需要验证码的 urls */ private Set
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); }}
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。