Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
xyqb-user2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
head_group
xyqb-user2
Commits
977ac720
Commit
977ac720
authored
Jan 31, 2018
by
贷前—徐菲
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
极验
parent
c88d1ea1
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
942 additions
and
1 deletion
+942
-1
pom.xml
pom.xml
+5
-0
Constants.java
src/main/java/cn/quantgroup/xyqb/Constants.java
+6
-0
CaptchaNewValidateAdvisor.java
...tgroup/xyqb/aspect/captcha/CaptchaNewValidateAdvisor.java
+125
-0
CaptchaNewValidator.java
...n/quantgroup/xyqb/aspect/captcha/CaptchaNewValidator.java
+13
-0
NewCaptchaController.java
...yqb/controller/external/captcha/NewCaptchaController.java
+60
-0
UserAuthorized.java
src/main/java/cn/quantgroup/xyqb/entity/UserAuthorized.java
+1
-1
GeetestCaptchaServiceImpl.java
...qb/service/captcha/geetest/GeetestCaptchaServiceImpl.java
+65
-0
IGeetestCaptchaService.java
.../xyqb/service/captcha/geetest/IGeetestCaptchaService.java
+46
-0
GeetestLib.java
...antgroup/xyqb/service/captcha/geetest/sdk/GeetestLib.java
+552
-0
IQuantgroupCaptchaService.java
...up/xyqb/service/captcha/qg/IQuantgroupCaptchaService.java
+18
-0
QuantgroupCaptchaServiceImpl.java
...xyqb/service/captcha/qg/QuantgroupCaptchaServiceImpl.java
+51
-0
No files found.
pom.xml
View file @
977ac720
...
@@ -338,6 +338,11 @@
...
@@ -338,6 +338,11 @@
<artifactId>
sentry-spring
</artifactId>
<artifactId>
sentry-spring
</artifactId>
<version>
1.6.3
</version>
<version>
1.6.3
</version>
</dependency>
</dependency>
<dependency>
<groupId>
com.vaadin.external.google
</groupId>
<artifactId>
android-json
</artifactId>
<version>
0.0.20131108.vaadin1
</version>
</dependency>
</dependencies>
</dependencies>
...
...
src/main/java/cn/quantgroup/xyqb/Constants.java
View file @
977ac720
...
@@ -94,4 +94,10 @@ public interface Constants {
...
@@ -94,4 +94,10 @@ public interface Constants {
String
AES_KEY
=
"ScnmRBhuQpo9kBdn"
;
String
AES_KEY
=
"ScnmRBhuQpo9kBdn"
;
String
GEETEST_ID
=
"002bc30ff1eef93e912f45814945e752"
;
String
GEETEST_KEY
=
"4193a0e3247b82a26f563d595c447b1a"
;
boolean
NEW_FAIL_BACK
=
true
;
String
GT_SERVER_STATUS_SESSION_KEY
=
"gt_server_status"
;
String
GT_SERVER_STATUS_USABLE
=
"1"
;
Long
GT_SERVER_STATUS_EXIST_REDIS
=
2L
;
}
}
src/main/java/cn/quantgroup/xyqb/aspect/captcha/CaptchaNewValidateAdvisor.java
0 → 100644
View file @
977ac720
package
cn
.
quantgroup
.
xyqb
.
aspect
.
captcha
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.service.captcha.geetest.IGeetestCaptchaService
;
import
cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService
;
import
cn.quantgroup.xyqb.util.IPUtil
;
import
com.octo.captcha.service.CaptchaServiceException
;
import
lombok.extern.slf4j.Slf4j
;
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.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
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletRequest
;
import
java.nio.charset.Charset
;
import
java.util.Optional
;
import
java.util.UUID
;
/**
* @author xufei on 2018/1/30.
*/
@Aspect
@Component
@Slf4j
public
class
CaptchaNewValidateAdvisor
{
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__"
;
@Resource
private
IGeetestCaptchaService
geetestCaptchaService
;
@Resource
@Qualifier
(
"stringRedisTemplate"
)
private
RedisTemplate
<
String
,
String
>
stringRedisTemplate
;
@Resource
@Qualifier
(
"customCaptchaService"
)
private
AbstractManageableImageCaptchaService
imageCaptchaService
;
/**
* 自动化测试忽略验证码
*/
@Value
(
"${xyqb.auth.captcha.autotest.enable:false}"
)
private
boolean
autoTestCaptchaEnabled
;
/**
* 图形验证码切面
*/
@Pointcut
(
"@annotation(cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator)"
)
private
void
needCaptchaValidate
()
{
}
/**
* 在受图形验证码保护的接口方法执行前, 执行图形验证码校验
*
* @param pjp pjp
* @return
* @throws Throwable
* @return
*/
@Around
(
"needCaptchaValidate()"
)
private
Object
doCaptchaValidate
(
ProceedingJoinPoint
pjp
)
throws
Throwable
{
HttpServletRequest
request
=
((
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
()).
getRequest
();
//测试环境使用QG图形验证码
if
(
autoTestCaptchaEnabled
){
quantgroupCaptchaValidate
(
pjp
,
request
);
}
String
phoneNo
=
Optional
.
ofNullable
(
request
.
getParameter
(
"phoneNo"
)).
orElse
(
""
);
String
captchaKey
=
Constants
.
GT_SERVER_STATUS_SESSION_KEY
+
phoneNo
;
if
(
stringRedisTemplate
.
hasKey
(
captchaKey
)
&&
Constants
.
GT_SERVER_STATUS_USABLE
.
equals
(
stringRedisTemplate
.
opsForValue
().
get
(
captchaKey
)))
{
geetestCaptchaService
.
verifyLogin
(
phoneNo
,
request
);
log
.
info
(
"使用极验验证码,phoneNo:{}"
,
phoneNo
);
return
pjp
.
proceed
();
}
else
{
return
quantgroupCaptchaValidate
(
pjp
,
request
);
}
}
private
Object
quantgroupCaptchaValidate
(
ProceedingJoinPoint
pjp
,
HttpServletRequest
request
)
throws
Throwable
{
String
registerFrom
=
Optional
.
ofNullable
(
request
.
getParameter
(
"registerFrom"
)).
orElse
(
""
);
String
captchaId
=
Optional
.
ofNullable
(
request
.
getParameter
(
"captchaId"
)).
orElse
(
""
);
String
captchaValue
=
request
.
getParameter
(
"captchaValue"
);
if
(
isSkipCaptchaValidate
(
captchaId
,
captchaValue
))
{
log
.
info
(
"使用超级图形验证码校验, registerFrom={}, clientIp={}"
,
registerFrom
,
IPUtil
.
getRemoteIP
(
request
));
return
pjp
.
proceed
();
}
return
verifyCaptchaOnline
(
pjp
,
captchaId
,
captchaValue
);
}
private
Object
verifyCaptchaOnline
(
ProceedingJoinPoint
pjp
,
String
captchaId
,
String
captchaValue
)
throws
Throwable
{
JsonResult
result
=
JsonResult
.
buildSuccessResult
(
"图形验证码不正确"
,
""
);
result
.
setBusinessCode
(
"0002"
);
if
(
org
.
apache
.
commons
.
lang3
.
StringUtils
.
isNotBlank
(
captchaValue
))
{
// 忽略用户输入的大小写
String
captcha
=
org
.
apache
.
commons
.
lang3
.
StringUtils
.
lowerCase
(
captchaValue
);
// 验证码校验
Boolean
validCaptcha
=
false
;
try
{
validCaptcha
=
imageCaptchaService
.
validateResponseForID
(
Constants
.
IMAGE_CAPTCHA_KEY
+
captchaId
,
captcha
);
}
catch
(
CaptchaServiceException
ex
)
{
log
.
error
(
"验证码校验异常, {}, {}"
,
ex
.
getMessage
(),
ex
);
}
if
(
validCaptcha
)
{
return
pjp
.
proceed
();
}
}
return
result
;
}
private
boolean
isSkipCaptchaValidate
(
String
captchaId
,
Object
captchaValue
)
{
// 如果启用了超级验证码功能, 检查超级验证码, 超级验证码区分大小写
return
autoTestCaptchaEnabled
||
org
.
apache
.
commons
.
lang3
.
StringUtils
.
equals
(
SUPER_CAPTCHA_ID
,
String
.
valueOf
(
captchaId
))
&&
org
.
apache
.
commons
.
lang3
.
StringUtils
.
equals
(
SUPER_CAPTCHA
,
String
.
valueOf
(
captchaValue
));
}
}
src/main/java/cn/quantgroup/xyqb/aspect/captcha/CaptchaNewValidator.java
0 → 100644
View file @
977ac720
package
cn
.
quantgroup
.
xyqb
.
aspect
.
captcha
;
import
java.lang.annotation.*
;
/**
* @author xufei on 2018/1/30.
*/
@Documented
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
CaptchaNewValidator
{
}
src/main/java/cn/quantgroup/xyqb/controller/external/captcha/NewCaptchaController.java
0 → 100644
View file @
977ac720
package
cn
.
quantgroup
.
xyqb
.
controller
.
external
.
captcha
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator
;
import
cn.quantgroup.xyqb.aspect.logcaller.LogHttpCaller
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.service.captcha.geetest.IGeetestCaptchaService
;
import
cn.quantgroup.xyqb.service.captcha.geetest.sdk.GeetestLib
;
import
cn.quantgroup.xyqb.service.captcha.qg.IQuantgroupCaptchaService
;
import
cn.quantgroup.xyqb.util.ValidationUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletRequest
;
/**
* @author xufei on 2018/1/30.
*/
@Slf4j
@RestController
@RequestMapping
(
"/api"
)
public
class
NewCaptchaController
{
@Resource
private
IGeetestCaptchaService
geetestCaptchaService
;
@Resource
private
IQuantgroupCaptchaService
quantgroupCaptchaService
;
@LogHttpCaller
@RequestMapping
(
value
=
"/newCaptcha"
)
public
JsonResult
getCaptcha
(
HttpServletRequest
request
,
String
phoneNo
)
{
if
(!
ValidationUtil
.
validatePhoneNo
(
phoneNo
))
{
return
JsonResult
.
buildErrorStateResult
(
"手机号格式错误"
,
null
);
}
log
.
info
(
"[newCaptcha]获取验证码,phoneNo:{}"
,
phoneNo
);
GeetestLib
gtSdk
=
geetestCaptchaService
.
getGeetestSdk
();
if
(
geetestCaptchaService
.
getGeetestServerStatus
(
phoneNo
,
request
,
gtSdk
)
==
Integer
.
parseInt
(
Constants
.
GT_SERVER_STATUS_USABLE
))
{
log
.
info
(
"[newCaptcha]极验可用,phoneNo:{}"
,
phoneNo
);
return
JsonResult
.
buildSuccessResult
(
""
,
geetestCaptchaService
.
startCaptcha
(
gtSdk
));
}
else
{
try
{
return
JsonResult
.
buildSuccessResult
(
""
,
quantgroupCaptchaService
.
fetchCaptcha
(
request
));
}
catch
(
Exception
e
)
{
log
.
error
(
"获取验证码失败e:{}"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
""
,
"fail"
);
}
}
}
@CaptchaNewValidator
@RequestMapping
(
"/new_verification_image_code"
)
public
JsonResult
verificationImageCode
()
{
return
JsonResult
.
buildSuccessResult
(
""
,
null
);
}
}
src/main/java/cn/quantgroup/xyqb/entity/UserAuthorized.java
View file @
977ac720
...
@@ -18,7 +18,7 @@ public class UserAuthorized {
...
@@ -18,7 +18,7 @@ public class UserAuthorized {
@Id
@Id
@Column
(
name
=
"id"
)
@Column
(
name
=
"id"
)
@GeneratedValue
(
generator
=
"uuid"
)
@GeneratedValue
(
generator
=
"uuid"
)
@GenericGenerator
(
name
=
"uuid"
,
strategy
=
"
uuid
"
)
@GenericGenerator
(
name
=
"uuid"
,
strategy
=
"
org.hibernate.id.UUIDGenerator
"
)
private
String
id
;
private
String
id
;
@Column
(
name
=
"user_uuid"
)
@Column
(
name
=
"user_uuid"
)
...
...
src/main/java/cn/quantgroup/xyqb/service/captcha/geetest/GeetestCaptchaServiceImpl.java
0 → 100644
View file @
977ac720
package
cn
.
quantgroup
.
xyqb
.
service
.
captcha
.
geetest
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.service.captcha.geetest.sdk.GeetestLib
;
import
cn.quantgroup.xyqb.util.IPUtil
;
import
cn.quantgroup.xyqb.util.PasswordUtil
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.HashMap
;
import
java.util.concurrent.TimeUnit
;
/**
* @author xufei on 2018/1/30.
*/
@Service
public
class
GeetestCaptchaServiceImpl
implements
IGeetestCaptchaService
{
@Resource
@Qualifier
(
"stringRedisTemplate"
)
private
RedisTemplate
<
String
,
String
>
stringRedisTemplate
;
@Override
public
GeetestLib
getGeetestSdk
()
{
return
new
GeetestLib
(
Constants
.
GEETEST_ID
,
Constants
.
GEETEST_KEY
,
Constants
.
NEW_FAIL_BACK
);
}
@Override
public
int
getGeetestServerStatus
(
String
phoneNo
,
HttpServletRequest
request
,
GeetestLib
gtSdk
)
{
HashMap
<
String
,
String
>
param
=
getParam
(
phoneNo
,
request
);
int
gtServerStatus
=
gtSdk
.
preProcess
(
param
);
stringRedisTemplate
.
opsForValue
().
set
(
Constants
.
GT_SERVER_STATUS_SESSION_KEY
+
phoneNo
,
Integer
.
toString
(
gtServerStatus
),
Constants
.
GT_SERVER_STATUS_EXIST_REDIS
,
TimeUnit
.
MINUTES
);
//进行验证预处理
return
gtServerStatus
;
}
private
HashMap
<
String
,
String
>
getParam
(
String
phoneNo
,
HttpServletRequest
request
)
{
HashMap
<
String
,
String
>
param
=
new
HashMap
<>();
param
.
put
(
"user_id"
,
PasswordUtil
.
MD5
(
phoneNo
));
param
.
put
(
"client_type"
,
"H5"
);
param
.
put
(
"ip_address"
,
IPUtil
.
getRemoteIP
(
request
));
return
param
;
}
@Override
public
String
startCaptcha
(
GeetestLib
gtSdk
)
{
return
gtSdk
.
getResponseStr
();
}
@Override
public
int
verifyLogin
(
String
phoneNo
,
HttpServletRequest
request
)
{
HashMap
<
String
,
String
>
param
=
getParam
(
phoneNo
,
request
);
String
challenge
=
request
.
getParameter
(
GeetestLib
.
fn_geetest_challenge
);
String
validate
=
request
.
getParameter
(
GeetestLib
.
fn_geetest_validate
);
String
seccode
=
request
.
getParameter
(
GeetestLib
.
fn_geetest_seccode
);
return
getGeetestSdk
().
enhencedValidateRequest
(
challenge
,
validate
,
seccode
,
param
);
}
}
src/main/java/cn/quantgroup/xyqb/service/captcha/geetest/IGeetestCaptchaService.java
0 → 100644
View file @
977ac720
package
cn
.
quantgroup
.
xyqb
.
service
.
captcha
.
geetest
;
import
cn.quantgroup.xyqb.service.captcha.geetest.sdk.GeetestLib
;
import
javax.servlet.http.HttpServletRequest
;
/**
* @author xufei on 2018/1/30.
*/
public
interface
IGeetestCaptchaService
{
/**
* 获取极验的sdk
*
* @return
*/
GeetestLib
getGeetestSdk
();
/**
* 获取geetest服务器可用的状态
*
* @param phoneNo 用户的手机号
* @param request rq
* @param gtSdk sdk
* @return 成功返回1, 失败返回0
*/
int
getGeetestServerStatus
(
String
phoneNo
,
HttpServletRequest
request
,
GeetestLib
gtSdk
);
/**
* 获取geetest的验证码
*
* @param gtSdk sdk
* @return
*/
String
startCaptcha
(
GeetestLib
gtSdk
);
/**
* 二次验证
*
* @param phoneNo 参数
* @param request rq
* @return 验证结果, 1表示验证成功0表示验证失败
*/
int
verifyLogin
(
String
phoneNo
,
HttpServletRequest
request
);
}
src/main/java/cn/quantgroup/xyqb/service/captcha/geetest/sdk/GeetestLib.java
0 → 100644
View file @
977ac720
This diff is collapsed.
Click to expand it.
src/main/java/cn/quantgroup/xyqb/service/captcha/qg/IQuantgroupCaptchaService.java
0 → 100644
View file @
977ac720
package
cn
.
quantgroup
.
xyqb
.
service
.
captcha
.
qg
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.Map
;
/**
* @author xufei on 2018/1/30.
*/
public
interface
IQuantgroupCaptchaService
{
/**
* QG获取验证码
*
* @param request rq
* @return map
* @throws Exception EX
*/
Map
<
String
,
String
>
fetchCaptcha
(
HttpServletRequest
request
)
throws
Exception
;
}
src/main/java/cn/quantgroup/xyqb/service/captcha/qg/QuantgroupCaptchaServiceImpl.java
0 → 100644
View file @
977ac720
package
cn
.
quantgroup
.
xyqb
.
service
.
captcha
.
qg
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService
;
import
org.apache.commons.codec.binary.Base64
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
javax.imageio.ImageIO
;
import
javax.servlet.http.HttpServletRequest
;
import
java.awt.image.BufferedImage
;
import
java.io.ByteArrayOutputStream
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.UUID
;
/**
* @author xufei on 2018/1/30.
*/
@Service
public
class
QuantgroupCaptchaServiceImpl
implements
IQuantgroupCaptchaService
{
private
static
final
String
IMAGE_FORMAT_PNG
=
"png"
;
private
static
final
String
IMG_BASE64_PATTREN
=
"data:image/"
+
IMAGE_FORMAT_PNG
+
";base64,%s"
;
/**
* 自动化测试忽略验证码
*/
@Value
(
"${xyqb.auth.captcha.autotest.enable:false}"
)
private
boolean
autoTestCaptchaEnabled
;
@Autowired
@Qualifier
(
"customCaptchaService"
)
private
AbstractManageableImageCaptchaService
imageCaptchaService
;
@Override
public
Map
<
String
,
String
>
fetchCaptcha
(
HttpServletRequest
request
)
throws
Exception
{
String
imageId
=
UUID
.
randomUUID
().
toString
();
BufferedImage
challenge
=
imageCaptchaService
.
getImageChallengeForID
(
Constants
.
IMAGE_CAPTCHA_KEY
+
imageId
,
request
.
getLocale
());
ByteArrayOutputStream
jpegOutputStream
=
new
ByteArrayOutputStream
();
ImageIO
.
write
(
challenge
,
IMAGE_FORMAT_PNG
,
jpegOutputStream
);
String
imageBase64
=
Base64
.
encodeBase64String
(
jpegOutputStream
.
toByteArray
());
Map
<
String
,
String
>
data
=
new
HashMap
<>();
data
.
put
(
"imageId"
,
imageId
);
data
.
put
(
"image"
,
String
.
format
(
IMG_BASE64_PATTREN
,
imageBase64
));
return
data
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment