重构验证码校验接口

This commit is contained in:
lsy
2017-12-14 22:41:03 +08:00
parent 88773ba4df
commit 577ecdaf3f
8 changed files with 127 additions and 3 deletions
@@ -92,7 +92,7 @@ public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
.userDetailsService(userDetailsService)//设置获取用户信息后登录的方式
.and()
.authorizeRequests()//下面是权限配置
.antMatchers("/user/login", "/code/image", "/authentication/require", securityProperties.getBrowser().getHtml()).permitAll()//当访问这个页面的时候不进行身份认证,对用户自定义的登录页也不进行权限认证
.antMatchers("/user/login", "/code/*", "/authentication/require", securityProperties.getBrowser().getHtml()).permitAll()//当访问这个页面的时候不进行身份认证,对用户自定义的登录页也不进行权限认证
.anyRequest()//任何请求
.authenticated()//都需要身份认证
.and()
@@ -4,11 +4,12 @@
本项目说明中的配置参数是boot-starter-security-browser和boot-starter-security-app
项目的交集
- 用户登录接口url`/user/login`
- 验证码获取接口url`/code/image`
- 图片验证码获取接口url`/code/image`
- `ms.security.code.image.width` 图片验证码宽度,默认值是`67` 可以在请求中使用`width`参数设置
- `ms.security.code.image.height`图片验证码高度,默认值是`23` 可以在请求中使用`height`参数设置
- `ms.security.code.image.length`图片验证码的code长度,默认是`4` 不能在请求中设置
- `ms.security.code.image.expireIn` 图片验证码的有效时间`60`秒 不能在请求中设置
- `ms.security.code.image.url` 需要进行验证码校验的地址,默认值是`/user/login` 可以是`/user/*`这种格式,多个适用,号分割 不能在请求中设置
- 本着增量开发的原则,可以实现`imageCodeUtil`生成验证码的方法,并定义名称为`validateCodeUtil`的bean便可替换原有的验证码的生成逻辑
- 短信验证码获取接口url`/code/sms` 短信验证码
@@ -8,4 +8,5 @@ public class ValidateCodeConst {
* 从session中获取验证码校验对象的key
*/
public static final String SESSION_KEY_IMAGE_CODE = "SESSION_KEY_IMAGE_CODE";
}
@@ -40,7 +40,7 @@ public class ValidateCodeController {
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
@GetMapping("/code/image")
@GetMapping("/code/{type}")
public void createCode(HttpServletResponse response, HttpServletRequest request) throws IOException {
ImageCode imageCode = (ImageCode) imageCodeUtil.createValidateCode(new ServletWebRequest(request));
ValidateCode validateCode = new ValidateCode(imageCode.getCode(),imageCode.getExpireTime());
@@ -0,0 +1,21 @@
package com.micro.fast.security.core.validate.code.processor;
import org.springframework.web.context.request.ServletWebRequest;
/**
* 验证码校验controller中需要执行操作的抽象接口
*/
public interface ValidateCodeProcessor {
/**
* 验证码存储到session中的前缀
*/
String SESSION_KEY_PREFIX = "SESSION_KEY_FOR_CODE_";
/**
* 创建验证码,将验证码写入session中,输出验证码
* @param servletWebRequest 封装请求和响应
*/
void create(ServletWebRequest servletWebRequest);
}
@@ -0,0 +1,83 @@
package com.micro.fast.security.core.validate.code.processor.impl;
import com.micro.fast.security.core.validate.code.pojo.ValidateCode;
import com.micro.fast.security.core.validate.code.processor.ValidateCodeProcessor;
import com.micro.fast.security.core.validate.code.util.ValidateCodeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.context.request.ServletWebRequest;
import java.util.Map;
/**
* 验证码controller中执行操作的抽象方法
*/
public abstract class AbstractValidateCodeProcessor <T extends ValidateCode> implements ValidateCodeProcessor {
/**
* 操作session的工具类
*/
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
/**
* 收集系统中所有{@link ValidateCodeUtil}的实现,并将bean的名字作为key
*/
@Autowired
private Map<String,ValidateCodeUtil> validateCodeUtils;
@Override
public void create(ServletWebRequest servletWebRequest) {
T generateCode = generateCode(servletWebRequest);
save(servletWebRequest,generateCode);
send(servletWebRequest,generateCode);
}
/**
* 根据请求的类型生成验证码
* @param servletWebRequest
* @return
*/
@SuppressWarnings("unchecked")
public T generateCode(ServletWebRequest servletWebRequest){
String processorType = getProcessorType(servletWebRequest);
//根据请求的类型获取指定的验证码生成器
ValidateCodeUtil validateCodeUtil = validateCodeUtils.get(processorType + "CodeUtil");
return (T) validateCodeUtil.createValidateCode(servletWebRequest);
}
/**
* 保存验证码
* @param servletWebRequest
* @param validateCode 生成的验证码
*/
public void save(ServletWebRequest servletWebRequest,T validateCode){
//转化成一般类型的验证码
ValidateCode saveValidateCode = new ValidateCode();
saveValidateCode.setCode(validateCode.getCode());
saveValidateCode.setExpireTime(validateCode.getExpireTime());
//向session中存储验证码
sessionStrategy.setAttribute(servletWebRequest
,SESSION_KEY_PREFIX+getProcessorType(servletWebRequest).toUpperCase()
,saveValidateCode);
}
/**
* 发送验证码的逻辑,延迟到子类中去实现
* @param servletWebRequest
* @param validateCode 验证码对象
*/
public abstract void send(ServletWebRequest servletWebRequest,T validateCode);
/**
* 根据请求的url获取请求验证码的类型
* @param servletWebRequest
* @return type 获取请求验证码的类型
*/
private String getProcessorType(ServletWebRequest servletWebRequest){
return StringUtils.substringAfter(servletWebRequest.getRequest().getRequestURI(),"/code/");
}
}
@@ -0,0 +1,10 @@
package com.micro.fast.security.core.validate.code.processor.impl;
import org.springframework.stereotype.Component;
/**
* 图片验证码逻辑类
*/
@Component("imageValidateCodeProcessor")
public class ImageValidateCodeProcessor {
}
@@ -0,0 +1,8 @@
package com.micro.fast.security.core.validate.code.processor.impl;
import org.springframework.stereotype.Component;
@Component("smsValidateCodeProcessor")
public class SmsValidateCodeProcessor {
}