@Component
(
"validateCodeFilter"
)
public
class
ValidateCodeFilter
extends
OncePerRequestFilter
implements
InitializingBean {
/**
* 验证码校验失败处理器
*/
@Autowired
private
AuthenticationFailureHandler authenticationFailureHandler;
/**
* 系统配置信息
*/
@Autowired
private
SecurityProperties securityProperties;
/**
* 系统中的校验码处理器
*/
@Autowired
private
ValidateCodeProcessorHolder validateCodeProcessorHolder;
/**
* 存放所有需要校验验证码的url
*/
private
Map<String, ValidateCodeType> urlMap =
new
HashMap<>();
/**
* 验证请求url与配置的url是否匹配的工具类
*/
private
AntPathMatcher pathMatcher =
new
AntPathMatcher();
/**
* 初始化要拦截的url配置信息
*/
@Override
public
void
afterPropertiesSet()
throws
ServletException {
super
.afterPropertiesSet();
urlMap.put(
"/authentication/mobile"
, ValidateCodeType.SMS);
addUrlToMap(securityProperties.getCode().getSms().getUrl(), ValidateCodeType.SMS);
}
/**
* 讲系统中配置的需要校验验证码的URL根据校验的类型放入map
*
* @param urlString
* @param type
*/
protected
void
addUrlToMap(String urlString, ValidateCodeType type) {
if
(StringUtils.isNotBlank(urlString)) {
String[] urls = StringUtils.splitByWholeSeparatorPreserveAllTokens(urlString,
","
);
for
(String url : urls) {
urlMap.put(url, type);
}
}
}
/**
* 验证短信验证码
*
* @param request
* @param response
* @param chain
* @throws ServletException
* @throws IOException
*/
@Override
protected
void
doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws
ServletException, IOException {
ValidateCodeType type = getValidateCodeType(request);
if
(type !=
null
) {
logger.info(
"校验请求("
+ request.getRequestURI() +
")中的验证码,验证码类型"
+ type);
try
{
validateCodeProcessorHolder.findValidateCodeProcessor(type)
.validate(
new
ServletWebRequest(request, response));
logger.info(
"验证码校验通过"
);
}
catch
(ValidateCodeException exception) {
authenticationFailureHandler.onAuthenticationFailure(request, response, exception);
return
;
}
}
chain.doFilter(request, response);
}
/**
* 获取校验码的类型,如果当前请求不需要校验,则返回null
*
* @param request
* @return
*/
private
ValidateCodeType getValidateCodeType(HttpServletRequest request) {
ValidateCodeType result =
null
;
if
(!StringUtils.equalsIgnoreCase(request.getMethod(),
"GET"
)) {
Set<String> urls = urlMap.keySet();
for
(String url : urls) {
if
(pathMatcher.match(url, request.getRequestURI())) {
result = urlMap.get(url);
}
}
}
return
result;
}
}