您的位置:首页 > 编程语言 > Java开发

Spring Security 实现图片验证码登陆(二)

2018-01-22 23:55 477 查看
重构图形验证码接口

验证码基本参数可配置

验证码拦截的接口可配置

验证码的生成逻辑

图形验证码基本参数配置



/**
* 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(); /* 关闭跨站请求攻击 */
}
}










常见的代码开发的一个思想

以增量的方式去适应变化 :当出现变化的时候,不如说图形验证码的逻辑出现改变了,原来的逻辑不满足了,那么处理的方式不是去修改原来的代码,而是新加了一段代码。

重构这件事情是永无止境的,代码永远可以变得更好
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: