Spring Security 实现图片验证码登陆(二)
2018-01-22 23:55
477 查看
重构图形验证码接口
验证码基本参数可配置
验证码拦截的接口可配置
验证码的生成逻辑
图形验证码基本参数配置
application.properties
常见的代码开发的一个思想
以增量的方式去适应变化 :当出现变化的时候,不如说图形验证码的逻辑出现改变了,原来的逻辑不满足了,那么处理的方式不是去修改原来的代码,而是新加了一段代码。
重构这件事情是永无止境的,代码永远可以变得更好
验证码基本参数可配置
验证码拦截的接口可配置
验证码的生成逻辑
图形验证码基本参数配置
/** * application.properties配置 * Created by ZhuPengWei on 2017/11/28. */ @ConfigurationProperties(prefix = "spring.security") //读取配置文件中所有以spring.security开头的文件 public class SecurityProperties { /** * 浏览器配置 */ private BrowserProperties browserProperties = new BrowserProperties(); /** * 校验类型 */ private ValidateCodeProperties validateCodeProperties = new ValidateCodeProperties(); ............ }
/** * 生成图片配置 * Created by ZhuPengWei on 2017/12/2. */ public class ImageCodeProperties { // 图片长度 private int length = 4; // 图片宽度 private int weight = 67; // 图片高度 private int height = 23; // 图片失效时间 private int expire = 60; // 图片过滤器 哪些情况下需要验证码 private String url; }
application.properties
#设置验证码的大小长度 过去时间等等 spring.security.validateCodeProperties.image.length = 5 spring.security.validateCodeProperties.image.weight = 67 spring.security.validateCodeProperties.image.height = 23 spring.security.validateCodeProperties.image.expire = 60 #哪些情况下需要生成图片验证码 spring.security.validateCodeProperties.image.url = /image,/image/*
/** * OncePerRequestFilter顾名思义,他能够确保在一次请求只通过一次filter,而不需要重复执行 * 实现InitializingBean的目的是在其他参数组装完毕之后去初始化参数的值 * Created by ZhuPengWei on 2017/12/1. */ public class ValidationCodeFilter extends OncePerRequestFilter implements InitializingBean { private AuthenticationFailureHandler authenticationFailureHandler; private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); private Set<String> urls = new HashSet<String>(); private SecurityProperties securityProperties; // Spring工具类 private AntPathMatcher pathMatcher = new AntPathMatcher(); @Override public void afterPropertiesSet() throws ServletException { super.afterPropertiesSet(); // 覆盖父类的实现 String[] configUrls = StringUtils.split(securityProperties.getValidateCodeProperties().getImage().getUrl(), ","); for (String url : configUrls) { urls.add(url); } urls.add("/authentication/form"); } @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain ) throws ServletException, IOException { boolean action = false; for ( String url : urls ) { if ( pathMatcher.match( url, request.getRequestURI() ) ) { action = true; break; } } if ( action && StringUtils.equalsIgnoreCase( "post", request.getMethod() ) ) { try { validate( new ServletWebRequest( request ) ); } catch ( ValidateCodeException e ) { authenticationFailureHandler.onAuthenticationFailure( request, response, e ); /* 不继续执行 */ return; } } /* 继续执行下一步 */ filterChain.doFilter( request, response ); } }
/** * 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); /* 注入 */ validationCodeFilter.setSecurityProperties(securityProperties); /* 初始化方法 */ validationCodeFilter.afterPropertiesSet(); 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,实现登陆验证、会话管理
- 一个基于wap1.0的web项目(图文)--实现登陆验证
- 拦截器实现对用户是否登录及登陆超时的验证
- JSP+Servlet实现图片验证码
- 在Spring中使用jcaptcha实现图片验证
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十四║ Vuex + JWT 实现授权验证登陆
- linux-apache安装实现登陆身份验证-023
- 使用spring security 实现权限的验证
- 字符型图片验证码识别完整过程及Python实现
- java实现图片验证码全套实现方式
- 【IOS】利用ASIHTTPRequest 实现一个简单的登陆验证
- Spring boot 整合shiro 实现登陆验证
- Java实现图片验证码源码
- 自己动手实现一次性图片验证码
- python实现简单的登陆验证
- Unity3d+PHP+Mysql 实现注册激活验证登陆
- ASP.NET Forms验证 实现子域名(SubDomain)共享登陆下的缺陷
- 简单的登陆注册的实现+验证码和表单验证