Commit c88d1ea1 authored by 贷前—徐菲's avatar 贷前—徐菲

Merge remote-tracking branch 'origin/master'

parents 865c856e e92fa962
...@@ -13,6 +13,7 @@ import org.springframework.context.ConfigurableApplicationContext; ...@@ -13,6 +13,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import sun.misc.Signal; import sun.misc.Signal;
...@@ -38,6 +39,10 @@ public class Bootstrap { ...@@ -38,6 +39,10 @@ public class Bootstrap {
log.info("server start..."); log.info("server start...");
// 启用平滑退出功能 // 启用平滑退出功能
Signal.handle(new Signal("INT"), new DefaultSignalHandler(run)); Signal.handle(new Signal("INT"), new DefaultSignalHandler(run));
Sentry.init("http://13ef5642903a414c910f8d0e0a2c56ee:8b351ad1abf44de3b4c25f39105fb927@172.16.4.89:9000/6"); // 异常log捕获
Environment environment = run.getBean(Environment.class);
String dsn = environment.getProperty("dsn");
Sentry.init(dsn);
} }
} }
...@@ -8,13 +8,11 @@ import org.aspectj.lang.annotation.Aspect; ...@@ -8,13 +8,11 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
/** /**
* IP白名单检验 * IP白名单检验
...@@ -27,18 +25,12 @@ import java.util.Objects; ...@@ -27,18 +25,12 @@ import java.util.Objects;
public class IpValidateAdvisor { public class IpValidateAdvisor {
private static final Logger LOGGER = LoggerFactory.getLogger(IpValidateAdvisor.class); private static final Logger LOGGER = LoggerFactory.getLogger(IpValidateAdvisor.class);
@Value("${configserver.disable}")
private Integer isDebug;
@Pointcut("execution(public * cn.quantgroup.xyqb.controller.external.user.InnerController.*(..)) || @annotation(cn.quantgroup.xyqb.aspect.accessable.IpValidator)") @Pointcut("execution(public * cn.quantgroup.xyqb.controller.external.user.InnerController.*(..)) || @annotation(cn.quantgroup.xyqb.aspect.accessable.IpValidator)")
private void whiteIpMatch() { private void whiteIpMatch() {
} }
@Around("whiteIpMatch()") @Around("whiteIpMatch()")
private Object doWhiteIpMatch(ProceedingJoinPoint pjp) throws Throwable { private Object doWhiteIpMatch(ProceedingJoinPoint pjp) throws Throwable {
if(Objects.equals(isDebug, 0)){
return pjp.proceed();
}
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
// 客户端IP // 客户端IP
String clientIp = IPUtil.getRemoteIP(request); String clientIp = IPUtil.getRemoteIP(request);
......
package cn.quantgroup.xyqb.aspect.captcha;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService;
import cn.quantgroup.xyqb.util.IPUtil;
import com.octo.captcha.service.CaptchaServiceException;
import java.nio.charset.Charset;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* 类名称:CaptchaValidateAdvisor
* 类描述:
*
* @author 李宁
* @version 1.0.0 创建时间:15/11/17 14:49
*/
@Aspect
@Component
public class CaptchaNewValidateAdvisor {
private static final Logger LOGGER = LoggerFactory.getLogger(CaptchaNewValidateAdvisor.class);
private static final String SUPER_CAPTCHA_ID = UUID.nameUUIDFromBytes("__QG_APPCLIENT_AGENT__".getBytes(Charset.forName("UTF-8"))).toString();
private static final String SUPER_CAPTCHA = "__SUPERQG__";
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
@Autowired
@Qualifier("customCaptchaService")
private AbstractManageableImageCaptchaService imageCaptchaService;
/**
* 自动化测试忽略验证码
*/
@Value("${xyqb.auth.captcha.autotest.enable:false}")
private boolean autoTestCaptchaEnabled;
private static final String IMAGE_IP_COUNT = "image:ip";
private static final String IMAGE_PHONE_COUNT = "image:phone";
private static final String IMAGE_DEVICEID_COUNT = "image:deviceId:";
private static final Long FIVE_MIN = 24 * 5L;
/**
* 图形验证码切面
*/
@Pointcut("@annotation(cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator)")
private void needNewCaptchaValidate() {
}
/**
* 在受图形验证码保护的接口方法执行前, 执行图形验证码校验
* captchaId 图形验证码key
* captchaValue 图形验证码value
*
* @throws Throwable
*/
@Around("needNewCaptchaValidate()")
private Object doCapchaValidate(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String registerFrom = Optional.ofNullable(request.getParameter("registerFrom")).orElse("");
String captchaId = Optional.ofNullable(request.getParameter("captchaId")).orElse("");
String captchaValue = request.getParameter("captchaValue");
String phoneNo = request.getParameter("phoneNo");
String deviceId = Optional.ofNullable(request.getParameter("deviceId")).orElse("");
String clientIp = IPUtil.getRemoteIP(request);
Long countIP = countByClientId(clientIp, false);
Long countPhone = countPhone(phoneNo);
Long countDeviceId = countByClientId(deviceId, true);
IPUtil.logIp(LOGGER, request);
LOGGER.info("使用图形验证码, registerFrom={}, clientIp={},手机号次数:{},设备次数:{},ip次数:{},phone:{}", registerFrom, clientIp,countPhone,countDeviceId,countIP,phoneNo);
//if (countIP > Constants.Image_Need_Count || countPhone > Constants.Image_Need_Count || countDeviceId > Constants.Image_Need_Count) {
if(true){
if (shouldSkipCaptchaValidate(registerFrom, captchaId, captchaValue)) {
LOGGER.info("使用超级图形验证码校验, registerFrom={}, clientIp={}", registerFrom, clientIp);
return pjp.proceed();
}
JsonResult result = JsonResult.buildSuccessResult("图形验证码不正确", "");
result.setBusinessCode("0002");
if (StringUtils.isNotBlank(captchaValue)) {
// 忽略用户输入的大小写
String captcha = StringUtils.lowerCase(captchaValue);
// 验证码校验
Boolean validCaptcha = false;
try {
validCaptcha = imageCaptchaService.validateResponseForID(Constants.IMAGE_CAPTCHA_KEY + captchaId, captcha);
} catch (CaptchaServiceException ex) {
LOGGER.error("验证码校验异常, {}, {}", ex.getMessage(), ex);
}
if (validCaptcha) {
return pjp.proceed();
}
return result;
}
LOGGER.info("使用错误图形验证码, registerFrom={}, clientIp={},手机号次数:{},设备次数:{},ip次数:{},phone:{}", registerFrom, clientIp,countPhone,countDeviceId,countIP,phoneNo);
result.setMsg("请输入图形验证码");
return result;
}
return pjp.proceed();
}
private boolean shouldSkipCaptchaValidate(String registerFrom, String captchaId, Object captchaValue) {
// 如果启用了超级验证码功能, 检查超级验证码, 超级验证码区分大小写
if (autoTestCaptchaEnabled) {
return true;
}
return StringUtils.equals(SUPER_CAPTCHA_ID, String.valueOf(captchaId)) && StringUtils.equals(SUPER_CAPTCHA, String.valueOf(captchaValue));
}
private Long countPhone(String phoneNo) {
Long count = 1L;
String countString = redisTemplate.opsForValue().get(IMAGE_PHONE_COUNT + phoneNo);
if (StringUtils.isBlank(countString)) {
redisTemplate.opsForValue().set(IMAGE_PHONE_COUNT + phoneNo, String.valueOf(count),
FIVE_MIN, TimeUnit.SECONDS);
} else {
count = Long.valueOf(countString) + 1L;
redisTemplate.opsForValue().set(IMAGE_PHONE_COUNT + phoneNo, String.valueOf(count),
FIVE_MIN, TimeUnit.SECONDS);
}
return count;
}
/**
* 短信发送限制
* @param clientId - 设备ID或IP
* @param device - true - 设备,false - IP
* @return
*/
private Long countByClientId(String clientId, boolean device) {
Long count = 1L;
if (StringUtils.isBlank(clientId)) {
return count;
} else {
String key = (device ? IMAGE_DEVICEID_COUNT : IMAGE_IP_COUNT) + clientId;
String countString = redisTemplate.opsForValue().get(key);
if (StringUtils.isBlank(countString)) {
redisTemplate.opsForValue().set(key, String.valueOf(count), FIVE_MIN, TimeUnit.SECONDS);
} else {
count = Long.valueOf(countString) + 1L;
redisTemplate.opsForValue().set(key, String.valueOf(count), FIVE_MIN, TimeUnit.SECONDS);
}
return count;
}
}
}
package cn.quantgroup.xyqb.aspect.captcha;
import java.lang.annotation.*;
/**
* Created by xuran on 2017/8/28.
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CaptchaNewValidator {
}
package cn.quantgroup.xyqb.aspect.captcha; package cn.quantgroup.xyqb.aspect.captcha;
import cn.quantgroup.xyqb.Constants; import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.model.JsonResult; import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService; import cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService;
...@@ -78,19 +77,16 @@ public class CaptchaValidateAdvisor { ...@@ -78,19 +77,16 @@ public class CaptchaValidateAdvisor {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String registerFrom = Optional.ofNullable(request.getParameter("registerFrom")).orElse(""); String registerFrom = Optional.ofNullable(request.getParameter("registerFrom")).orElse("");
String captchaId = Optional.ofNullable(request.getParameter("captchaId")).orElse(""); String captchaId = Optional.ofNullable(request.getParameter("captchaId")).orElse("");
Object captchaValue = request.getParameter("captchaValue"); String captchaValue = request.getParameter("captchaValue");
if (shouldSkipCaptchaValidate(registerFrom, captchaId, captchaValue)) { if (shouldSkipCaptchaValidate(registerFrom, captchaId, captchaValue)) {
LOGGER.info("使用超级图形验证码校验, registerFrom={}, clientIp={}", registerFrom, IPUtil.getRemoteIP(request)); LOGGER.info("使用超级图形验证码校验, registerFrom={}, clientIp={}", registerFrom, IPUtil.getRemoteIP(request));
return pjp.proceed(); return pjp.proceed();
} }
JsonResult result = JsonResult.buildSuccessResult("图形验证码不正确", ""); JsonResult result = JsonResult.buildSuccessResult("图形验证码不正确", "");
result.setBusinessCode("0002"); result.setBusinessCode("0002");
if (captchaValue != null) { if (StringUtils.isNotBlank(captchaValue)) {
String captcha = String.valueOf(captchaValue);
// 忽略用户输入的大小写 // 忽略用户输入的大小写
captcha = StringUtils.lowerCase(captcha); String captcha = StringUtils.lowerCase(captchaValue);
// 验证码校验 // 验证码校验
Boolean validCaptcha = false; Boolean validCaptcha = false;
try { try {
...@@ -98,7 +94,6 @@ public class CaptchaValidateAdvisor { ...@@ -98,7 +94,6 @@ public class CaptchaValidateAdvisor {
} catch (CaptchaServiceException ex) { } catch (CaptchaServiceException ex) {
LOGGER.error("验证码校验异常, {}, {}", ex.getMessage(), ex); LOGGER.error("验证码校验异常, {}, {}", ex.getMessage(), ex);
} }
if (validCaptcha) { if (validCaptcha) {
return pjp.proceed(); return pjp.proceed();
} }
......
...@@ -13,9 +13,6 @@ import org.aspectj.lang.annotation.Aspect; ...@@ -13,9 +13,6 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
...@@ -38,10 +35,6 @@ public class PasswordFreeAccessValidateAdvisor { ...@@ -38,10 +35,6 @@ public class PasswordFreeAccessValidateAdvisor {
private static final String PHONE_NO = "phoneNo"; private static final String PHONE_NO = "phoneNo";
private static final String USER_ID = "userId"; private static final String USER_ID = "userId";
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
/** /**
* 免密访问校验切面 * 免密访问校验切面
*/ */
......
...@@ -2,7 +2,6 @@ package cn.quantgroup.xyqb.controller.internal.sms; ...@@ -2,7 +2,6 @@ package cn.quantgroup.xyqb.controller.internal.sms;
import cn.quantgroup.sms.MsgParams; import cn.quantgroup.sms.MsgParams;
import cn.quantgroup.xyqb.Constants; import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator;
import cn.quantgroup.xyqb.aspect.captcha.CaptchaValidator; import cn.quantgroup.xyqb.aspect.captcha.CaptchaValidator;
import cn.quantgroup.xyqb.controller.IBaseController; import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.model.JsonResult; import cn.quantgroup.xyqb.model.JsonResult;
...@@ -200,7 +199,7 @@ public class SmsController implements IBaseController { ...@@ -200,7 +199,7 @@ public class SmsController implements IBaseController {
/** /**
* 快速登陆发送验证码新版 * 快速登陆发送验证码新版
*/ */
@CaptchaNewValidator @CaptchaValidator
@RequestMapping("/send_login_code_voice_new") @RequestMapping("/send_login_code_voice_new")
public JsonResult sendLoginCodeVoiceNew(@RequestParam String phoneNo, @RequestParam(required = false) String registerFrom, public JsonResult sendLoginCodeVoiceNew(@RequestParam String phoneNo, @RequestParam(required = false) String registerFrom,
String usage, @RequestParam(required = false) String deviceId) { String usage, @RequestParam(required = false) String deviceId) {
...@@ -216,7 +215,7 @@ public class SmsController implements IBaseController { ...@@ -216,7 +215,7 @@ public class SmsController implements IBaseController {
/** /**
* 快速登陆发送短信验证码 * 快速登陆发送短信验证码
*/ */
@CaptchaNewValidator @CaptchaValidator
@RequestMapping("/send_login_code_new") @RequestMapping("/send_login_code_new")
public JsonResult sendLoginSmsCodeNew(@RequestParam String phoneNo, @RequestParam(required = false) String registerFrom, @RequestParam(required = false) String deviceId,@RequestParam(required = false,defaultValue = "")String appName) { public JsonResult sendLoginSmsCodeNew(@RequestParam String phoneNo, @RequestParam(required = false) String registerFrom, @RequestParam(required = false) String deviceId,@RequestParam(required = false,defaultValue = "")String appName) {
LOGGER.info("快速登陆-发送验证码, phoneNo:{}, registerFrom:{}", phoneNo, registerFrom); LOGGER.info("快速登陆-发送验证码, phoneNo:{}, registerFrom:{}", phoneNo, registerFrom);
...@@ -225,7 +224,7 @@ public class SmsController implements IBaseController { ...@@ -225,7 +224,7 @@ public class SmsController implements IBaseController {
/** /**
* 快速登陆发送短信验证码 * 快速登陆发送短信验证码
*/ */
@CaptchaNewValidator @CaptchaValidator
@RequestMapping("/send_login_code_new_forH5") @RequestMapping("/send_login_code_new_forH5")
public JsonResult sendLoginSmsCodeNewForH5(@RequestParam String phoneNo, @RequestParam(required = false) String registerFrom, @RequestParam(required = false) String deviceId,@RequestParam(required = false,defaultValue = "")String appName) { public JsonResult sendLoginSmsCodeNewForH5(@RequestParam String phoneNo, @RequestParam(required = false) String registerFrom, @RequestParam(required = false) String deviceId,@RequestParam(required = false,defaultValue = "")String appName) {
LOGGER.info("快速登陆-发送验证码, phoneNo:{}, registerFrom:{}", phoneNo, registerFrom); LOGGER.info("快速登陆-发送验证码, phoneNo:{}, registerFrom:{}", phoneNo, registerFrom);
......
...@@ -76,5 +76,5 @@ public class UserDetailController implements IBaseController { ...@@ -76,5 +76,5 @@ public class UserDetailController implements IBaseController {
return JsonResult.buildErrorStateResult("身份证号码错误", null); return JsonResult.buildErrorStateResult("身份证号码错误", null);
} }
} }
} }
...@@ -9,11 +9,13 @@ import cn.quantgroup.xyqb.service.auth.IUserAuthorizedService; ...@@ -9,11 +9,13 @@ import cn.quantgroup.xyqb.service.auth.IUserAuthorizedService;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.text.ParseException; import java.text.ParseException;
import java.util.Objects;
/** /**
* @author xufei on 2018/1/5. * @author xufei on 2018/1/5.
...@@ -27,6 +29,7 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService { ...@@ -27,6 +29,7 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService {
@Resource @Resource
private IUserAuthorizedRepository userAuthorizedRepository; private IUserAuthorizedRepository userAuthorizedRepository;
@Cacheable(value = "user_authorized_idno_cache", key = "#idNo", unless = "#result == null", cacheManager = "cacheManager")
@Override @Override
public Boolean hasUserAuthorized(String idNo) { public Boolean hasUserAuthorized(String idNo) {
try { try {
...@@ -35,6 +38,7 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService { ...@@ -35,6 +38,7 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService {
} }
} catch (ParseException e) { } catch (ParseException e) {
LOGGER.error("[hasUserAuthorized]参数异常e:{}", e); LOGGER.error("[hasUserAuthorized]参数异常e:{}", e);
return Boolean.FALSE;
} }
UserAuthorized userAuthorized = userAuthorizedRepository.findByIdNo(idNo); UserAuthorized userAuthorized = userAuthorizedRepository.findByIdNo(idNo);
...@@ -62,6 +66,10 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService { ...@@ -62,6 +66,10 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService {
@Override @Override
public UserAuthorized createUserAuthorized(UserAuthorizedParam userAuthorizedParam) { public UserAuthorized createUserAuthorized(UserAuthorizedParam userAuthorizedParam) {
// 数据检查
if(Objects.isNull(userAuthorizedParam) || this.hasUserAuthorized(userAuthorizedParam.getIdNo())){
return null;
}
AuthPattern authPatternEnum = AuthPattern.valueOf(userAuthorizedParam.getAuthPattern()); AuthPattern authPatternEnum = AuthPattern.valueOf(userAuthorizedParam.getAuthPattern());
UserAuthorized userAuthorized = new UserAuthorized(); UserAuthorized userAuthorized = new UserAuthorized();
...@@ -84,6 +92,7 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService { ...@@ -84,6 +92,7 @@ public class UserAuthorizedServiceImpl implements IUserAuthorizedService {
} }
} }
@Cacheable(value = "user_authorized_uuid_2_id_cache", key = "#userUuid", unless = "#result == null", cacheManager = "cacheManager")
@Override @Override
public String getUserAuthorizedId(String userUuid) { public String getUserAuthorizedId(String userUuid) {
if (StringUtils.isBlank(userUuid)) { if (StringUtils.isBlank(userUuid)) {
......
...@@ -32,6 +32,7 @@ public class IPUtil { ...@@ -32,6 +32,7 @@ public class IPUtil {
String jvmTest = System.getProperty("test"); String jvmTest = System.getProperty("test");
if(Boolean.valueOf(jvmTest)){ if(Boolean.valueOf(jvmTest)){
WHITE_ADDRESS.add("192.168."); WHITE_ADDRESS.add("192.168.");
WHITE_ADDRESS.add("10.");
WHITE_ADDRESS.add(LOCAL_ADDRESS); WHITE_ADDRESS.add(LOCAL_ADDRESS);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment