package cn.exrick.xboot.core.config.security.validate;
|
|
import cn.exrick.xboot.core.common.constant.SettingConstant;
|
import cn.exrick.xboot.core.common.redis.RedisTemplateHelper;
|
import cn.exrick.xboot.core.common.utils.IpInfoUtil;
|
import cn.exrick.xboot.core.common.utils.ResponseUtil;
|
import cn.exrick.xboot.core.config.properties.CaptchaProperties;
|
import cn.exrick.xboot.core.entity.Setting;
|
import cn.exrick.xboot.core.service.SettingService;
|
import cn.exrick.xboot.core.vo.VaptchaSetting;
|
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.http.HttpUtil;
|
import com.google.gson.Gson;
|
import com.google.gson.JsonParser;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.util.PathMatcher;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
|
import javax.servlet.FilterChain;
|
import javax.servlet.ServletException;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
|
/**
|
* 图形验证码过滤器
|
* @author Exrick
|
*/
|
@Slf4j
|
@Configuration
|
public class VaptchaValidateFilter extends OncePerRequestFilter {
|
|
@Autowired
|
private CaptchaProperties captchaProperties;
|
|
@Autowired
|
private SettingService settingService;
|
|
@Autowired
|
private IpInfoUtil ipInfoUtil;
|
|
@Autowired
|
private PathMatcher pathMatcher;
|
|
@Autowired
|
private RedisTemplateHelper redisTemplate;
|
|
@Override
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
|
|
// 判断URL是否需要验证
|
Boolean flag = false;
|
String requestUrl = request.getRequestURI();
|
for (String url : captchaProperties.getVaptcha()) {
|
if (pathMatcher.match(url, requestUrl)) {
|
flag = true;
|
break;
|
}
|
}
|
if (flag) {
|
String token = request.getParameter("token");
|
if (StrUtil.isBlank(token)) {
|
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "请传入Vaptcha验证码所需参数token"));
|
return;
|
}
|
String mode = token.substring(0, 7);
|
if (SettingConstant.OFFLINE_MODE.equals(mode)) {
|
// 离线模式 中间32位为knock
|
String knock = token.substring(7, 39);
|
String sessionToken = redisTemplate.get(knock);
|
// 最后为uuid
|
String uuid = token.substring(39);
|
if (StrUtil.isBlank(sessionToken) || !uuid.equals(sessionToken)) {
|
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "Vaptcha验证码验证失败"));
|
return;
|
}
|
// 验证成功 放行
|
chain.doFilter(request, response);
|
return;
|
} else {
|
Setting setting = settingService.get(SettingConstant.VAPTCHA_SETTING);
|
if (StrUtil.isBlank(setting.getValue())) {
|
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "系统还未配置Vaptcha验证码,请联系管理员"));
|
return;
|
}
|
VaptchaSetting vs = new Gson().fromJson(setting.getValue(), VaptchaSetting.class);
|
// 验证vaptcha验证码
|
String params = "id=" + vs.getVid() + "&secretkey=" + vs.getSecretKey() + "&token=" + token
|
+ "&ip=" + ipInfoUtil.getIpAddr(request);
|
String result = HttpUtil.post(SettingConstant.VAPTCHA_URL, params);
|
int success = JsonParser.parseString(result).getAsJsonObject().get("success").getAsInt();
|
if (success != 1) {
|
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "Vaptcha验证码验证失败"));
|
return;
|
}
|
// 验证成功 放行
|
chain.doFilter(request, response);
|
return;
|
}
|
}
|
// 无需验证 放行
|
chain.doFilter(request, response);
|
}
|
}
|