Spring Security 实现图片验证码登陆(一)
2018-01-22 22:06
495 查看
生成图形验证码
根据随机数生成图片
将随机数存到session中
在将生成的图片写到接口的响应中
在收到服务请求之后 根据随机数生成图片 ,然后把随机数存入到session中,在提交表单的时候从session中把随机数拿出来,和用户填写的验证码做一个比对
自定义过滤器
自定义过滤器
自定义异常
根据随机数生成图片
将随机数存到session中
在将生成的图片写到接口的响应中
在收到服务请求之后 根据随机数生成图片 ,然后把随机数存入到session中,在提交表单的时候从session中把随机数拿出来,和用户填写的验证码做一个比对
/** * 封装验证码信息 * Created by ZhuPengWei on 2017/12/1. */ public class ImageCode { /** * 图片 展示用 */ private BufferedImage image; /** * 随机数 */ private String code; /** * 过期时间 */ private LocalDateTime localDateTime; public ImageCode(BufferedImage image, String code, int second) { this.image = image; this.code = code; // 多少秒后 this.localDateTime = LocalDateTime.now().plusSeconds(second); } public ImageCode(BufferedImage image, String code, LocalDateTime localDateTime) { this.image = image; this.code = code; this.localDateTime = localDateTime; } 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 getLocalDateTime() { return localDateTime; } public void setLocalDateTime(LocalDateTime localDateTime) { this.localDateTime = localDateTime; } }
@RestController public class ValidateCodeController { private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); private static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; @GetMapping("/code/image") public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException { // 1.根据随机数生成图片 ImageCode imageCode = createImageCode(request); // 2.将图片存入session中 sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode); // 3.将生成的图片写入到接口响应中 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, 500)); 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 < 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(); 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); } }
自定义过滤器
/** * 封装验证码信息 * Created by ZhuPengWei on 2017/12/1. */ public class ImageCode { /** * 图片 展示用 */ private BufferedImage image; /** * 随机数 */ private String code; /** * 过期时间 */ private LocalDateTime localDateTime; public ImageCode(BufferedImage image, String code, int second) { this.image = image; this.code = code; // 多少秒后 this.localDateTime = LocalDateTime.now().plusSeconds(second); } public ImageCode(BufferedImage image, String code, LocalDateTime localDateTime) { this.image = image; this.code = code; this.localDateTime = localDateTime; } 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 getLocalDateTime() { return localDateTime; } public void setLocalDateTime(LocalDateTime localDateTime) { this.localDateTime = localDateTime; } }
@RestController public class ValidateCodeController { private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); private static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; @GetMapping("/code/image") public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException { // 1.根据随机数生成图片 ImageCode imageCode = createImageCode(request); // 2.将图片存入session中 sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode); // 3.将生成的图片写入到接口响应中 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, 500)); 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 < 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(); return new ImageCode(image, sRand, 60); } }
@RestController public class ValidateCodeController { private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); private static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; @GetMapping("/code/image") public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException { // 1.根据随机数生成图片 ImageCode imageCode = createImageCode(request); // 2.将图片存入session中 sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode); // 3.将生成的图片写入到接口响应中 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, 500)); 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 < 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(); return new ImageCode(image, sRand, 60); } }
自定义过滤器
/** * OncePerRequestFilter顾名思义,他能够确保在一次请求只通过一次filter,而不需要重复执行 * Created by ZhuPengWei on 2017/12/1. */ public class ValidationCodeFilter extends OncePerRequestFilter { private AuthenticationFailureHandler authenticationFailureHandler; private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (StringUtils.equals("/code/image", request.getRequestURI()) && StringUtils.equalsIgnoreCase("post", request.getMethod())) { try { validate(new ServletWebRequest(request)); } catch (ValidateCodeException e) { authenticationFailureHandler.onAuthenticationFailure(request, response, e); // 不继续执行 return; } } // 继续执行下一步 filterChain.doFilter(request, response); } private void validate(ServletWebRequest request) throws ServletRequestBindingException { // 从Session中获取imageCode对象 ImageCode imageCode = (ImageCode) sessionStrategy.getAttribute(request, ValidateCodeController.SESSION_KEY); String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), "imageCode"); if (StringUtils.isBlank(codeInRequest)) { throw new ValidateCodeException("验证码为空或者不存在"); } if (imageCode.isExpire()) { throw new ValidateCodeException("验证码过期"); } if (!StringUtils.equals(codeInRequest, imageCode.getCode())) { throw new ValidateCodeException("验证码不匹配"); } // session 中移除key sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY); } }
自定义异常
/** * 自定义异常 * Created by ZhuPengWei on 2017/12/1. */ public class ValidateCodeException extends AuthenticationException { public ValidateCodeException(String msg) { super(msg); } }
/** * security配置 * Created by ZhuPengWei on 2017/11/27. */ @Configuration public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter { /* 处理密码加密解密逻辑 */ @Bean public PasswordEncoder passwordEncoder() { return(new BCryptPasswordEncoder() ); } @Autowired private SecurityProperties securityProperties; @Autowired private SelfDefineAuthenticationFailureHandler selfDefineAuthenticationFailureHandler; @Autowired private SelfDefineAuthenticationSuccessHandler selfDefineAuthenticationSuccessHandler; @Override protected void configure( HttpSecurity http ) throws Exception { ValidationCodeFilter validationCodeFilter = new ValidationCodeFilter(); /* 设置错误失败处理器 */ validationCodeFilter.setAuthenticationFailureHandler( selfDefineAuthenticationFailureHandler ); http.addFilterBefore( validationCodeFilter, UsernamePasswordAuthenticationFilter.class ) .formLogin() /* 表单登陆 */ /* .loginPage("/index_standard.html") // 自定义登陆页面 */ .loginPage( "/authentication/require" ).permitAll() .loginProcessingUrl( "/authentication/form" ) .successHandler( selfDefineAuthenticationSuccessHandler ) .failureHandler( selfDefineAuthenticationFailureHandler ) .and() .authorizeRequests() /* 请求授权 */ .antMatchers( "/index_standard.html" , securityProperties.getBrowserProperties().getLoginPage() , "/code/image" ) .permitAll() /* 匹配页面 */ .anyRequest() /* 任何请求 */ .authenticated() /* 都需要认证 */ .and().csrf().disable(); /* 关闭跨站请求攻击 */ } }
相关文章推荐
- Spring Security 实现图片验证码登陆(二)
- 图片登陆验证功能的实现
- Spring Security 4.1.3 实现UserDetailsService,实现登陆验证、会话管理
- [Android实例] 拖动滑块进行图片拼合验证方式的实现
- Glide结合Okhttp做cookie管理实现注册需求的图片验证码短信验证码功能
- C#实现登陆验证码图片的动态生成
- 一个漂亮的登陆页面(无图片 只有一个CSS实现的)
- php实现http登陆验证
- 在TOMCAT下实现基于表单验证的登陆方式
- js实现图片文件校验,验证上传的文件是图片和其后缀名,大小
- Spring Security Oauth2.0 实现短信验证码登录示例
- 【IOS】利用ASIHTTPRequest 实现一个简单的登陆验证
- 使用android-async-http-master框架实现手机登陆服务器端密码验证
- tomcat中修改角色及实现登陆验证框功能
- Spring security实现登陆和权限角色控制
- node.js实现图片验证码
- iOS图片验证码使用SDWeb实现的加载如何实现清理缓存点击刷新
- 利用web.config来实现登陆验证[测]
- JSP session对象以及图片验证码的实现
- ThinkPHP3.2.1图片验证码实现方法