Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
poc-api
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
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
poc
poc-api
Commits
5c402aa7
Commit
5c402aa7
authored
Jan 30, 2026
by
nick zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(software-copyright): 企业微信扫码/授权登录
parent
f4fb890f
Show whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
1721 additions
and
2 deletions
+1721
-2
LoginChannelBuilder.java
...ain/java/cn/com/poc/user/builder/LoginChannelBuilder.java
+3
-1
WecomLoginChannel.java
src/main/java/cn/com/poc/user/builder/WecomLoginChannel.java
+143
-0
UserLoginConstants.java
...in/java/cn/com/poc/user/constants/UserLoginConstants.java
+1
-0
MemberLoginRequestDto.java
src/main/java/cn/com/poc/user/dto/MemberLoginRequestDto.java
+13
-0
WecomBaseApi.java
src/main/java/cn/com/poc/user/wecom/api/WecomBaseApi.java
+15
-0
WecomServiceApi.java
src/main/java/cn/com/poc/user/wecom/api/WecomServiceApi.java
+46
-0
WecomTokenApi.java
src/main/java/cn/com/poc/user/wecom/api/WecomTokenApi.java
+36
-0
WecomConstant.java
...in/java/cn/com/poc/user/wecom/constant/WecomConstant.java
+22
-0
WecomBaseResult.java
...in/java/cn/com/poc/user/wecom/domain/WecomBaseResult.java
+31
-0
WecomCorpInfo.java
...main/java/cn/com/poc/user/wecom/domain/WecomCorpInfo.java
+43
-0
WecomLoginInfoResponse.java
.../cn/com/poc/user/wecom/domain/WecomLoginInfoResponse.java
+50
-0
WecomLoginUrlDto.java
...n/java/cn/com/poc/user/wecom/domain/WecomLoginUrlDto.java
+23
-0
WecomProviderAccessToken.java
...n/com/poc/user/wecom/domain/WecomProviderAccessToken.java
+23
-0
WecomSuiteAccessToken.java
...a/cn/com/poc/user/wecom/domain/WecomSuiteAccessToken.java
+23
-0
WecomUserInfo.java
...main/java/cn/com/poc/user/wecom/domain/WecomUserInfo.java
+68
-0
WecomUserInfo3rd.java
...n/java/cn/com/poc/user/wecom/domain/WecomUserInfo3rd.java
+150
-0
WecomUserProfile.java
...n/java/cn/com/poc/user/wecom/domain/WecomUserProfile.java
+68
-0
WecomProperties.java
...com/poc/user/wecom/domain/properties/WecomProperties.java
+57
-0
WecomCallbackRest.java
...in/java/cn/com/poc/user/wecom/rest/WecomCallbackRest.java
+19
-0
WecomLoginRest.java
src/main/java/cn/com/poc/user/wecom/rest/WecomLoginRest.java
+22
-0
WecomCallbackRestImpl.java
...n/com/poc/user/wecom/rest/impl/WecomCallbackRestImpl.java
+81
-0
WecomLoginRestImpl.java
...a/cn/com/poc/user/wecom/rest/impl/WecomLoginRestImpl.java
+97
-0
WecomComponentService.java
.../cn/com/poc/user/wecom/service/WecomComponentService.java
+47
-0
WecomLoginService.java
...java/cn/com/poc/user/wecom/service/WecomLoginService.java
+92
-0
WecomTokenService.java
...java/cn/com/poc/user/wecom/service/WecomTokenService.java
+76
-0
WecomUserService.java
.../java/cn/com/poc/user/wecom/service/WecomUserService.java
+47
-0
AesException.java
src/main/java/cn/com/poc/user/wecom/util/AesException.java
+52
-0
ByteGroup.java
src/main/java/cn/com/poc/user/wecom/util/ByteGroup.java
+30
-0
PKCS7Encoder.java
src/main/java/cn/com/poc/user/wecom/util/PKCS7Encoder.java
+52
-0
SHA1.java
src/main/java/cn/com/poc/user/wecom/util/SHA1.java
+44
-0
WXBizMsgCrypt.java
src/main/java/cn/com/poc/user/wecom/util/WXBizMsgCrypt.java
+183
-0
XMLParse.java
src/main/java/cn/com/poc/user/wecom/util/XMLParse.java
+47
-0
config-dev.properties
src/main/resources/framemax-config/config-dev.properties
+8
-0
config.properties
src/main/resources/framemax-config/config.properties
+9
-1
No files found.
src/main/java/cn/com/poc/user/builder/LoginChannelBuilder.java
View file @
5c402aa7
...
...
@@ -28,6 +28,8 @@ public class LoginChannelBuilder implements ApplicationContextAware {
return
applicationContext
.
getBean
(
EmailLoginChannel
.
class
);
}
else
if
(
UserLoginConstants
.
LoginType
.
MEMBER_PLATFOMR_GOOGLE
.
equals
(
loginChannel
)){
return
applicationContext
.
getBean
(
GoogleLoginChannel
.
class
);
}
else
if
(
UserLoginConstants
.
LoginType
.
MEMBER_PLATFOMR_WECOM
.
equals
(
loginChannel
))
{
return
applicationContext
.
getBean
(
WecomLoginChannel
.
class
);
}
throw
new
I18nMessageException
(
"exception/third.party.authorization.channel.abnormal"
);
}
...
...
src/main/java/cn/com/poc/user/builder/WecomLoginChannel.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
builder
;
import
cn.com.poc.common.utils.Assert
;
import
cn.com.poc.common.utils.StringUtils
;
import
cn.com.poc.equity.aggregate.MemberEquityService
;
import
cn.com.poc.user.dto.MemberLoginRequestDto
;
import
cn.com.poc.user.entity.MemberInfoEntity
;
import
cn.com.poc.user.query.CheckMemberInfoQueryCondition
;
import
cn.com.poc.user.query.CheckMemberInfoQueryItem
;
import
cn.com.poc.user.service.BizMemberInfoService
;
import
cn.com.poc.user.wecom.constant.WecomConstant
;
import
cn.com.poc.user.wecom.domain.WecomUserProfile
;
import
cn.com.poc.user.wecom.service.WecomLoginService
;
import
cn.com.yict.framemax.core.i18n.I18nMessageException
;
import
cn.com.yict.framemax.frame.service.FmxParamConfigService
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.util.List
;
@Service
public
class
WecomLoginChannel
implements
LoginChannelService
{
@Resource
private
WecomLoginService
wecomLoginService
;
@Resource
private
BizMemberInfoService
bizMemberInfoService
;
@Resource
private
MemberEquityService
memberEquityService
;
@Resource
private
FmxParamConfigService
fmxParamConfigService
;
@Override
public
MemberInfoEntity
doLogin
(
MemberLoginRequestDto
memberLoginRequest
)
throws
Exception
{
Assert
.
notBlank
(
memberLoginRequest
.
getAuthCode
());
Assert
.
notBlank
(
memberLoginRequest
.
getLoginType
(),
"loginType"
);
WecomUserProfile
profile
=
wecomLoginService
.
getUserProfile
(
memberLoginRequest
.
getAuthCode
(),
memberLoginRequest
.
getLoginType
());
if
(
profile
==
null
)
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
MemberInfoEntity
member
=
findExistingMember
(
profile
);
if
(
member
!=
null
)
{
return
member
;
}
return
registerByWecom
(
profile
);
}
private
MemberInfoEntity
findExistingMember
(
WecomUserProfile
profile
)
throws
Exception
{
if
(
StringUtils
.
isNotBlank
(
profile
.
getMobile
()))
{
MemberInfoEntity
member
=
findByMobile
(
profile
.
getMobile
());
if
(
member
!=
null
)
{
return
member
;
}
}
if
(
StringUtils
.
isNotBlank
(
profile
.
getEmail
()))
{
MemberInfoEntity
member
=
findByEmail
(
profile
.
getEmail
());
if
(
member
!=
null
)
{
return
member
;
}
}
String
account
=
buildWecomAccount
(
profile
);
if
(
StringUtils
.
isBlank
(
account
))
{
return
null
;
}
return
bizMemberInfoService
.
getMemberEntityByAccount
(
account
);
}
private
MemberInfoEntity
registerByWecom
(
WecomUserProfile
profile
)
{
String
account
=
resolveAccount
(
profile
);
if
(
StringUtils
.
isBlank
(
account
))
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
MemberInfoEntity
memberInfoEntity
=
new
MemberInfoEntity
();
memberInfoEntity
.
setAccount
(
account
);
memberInfoEntity
.
setNickName
(
StringUtils
.
defaultIfBlank
(
profile
.
getName
(),
account
));
memberInfoEntity
.
setAvatarUrl
(
resolveAvatar
(
profile
.
getAvatarUrl
()));
memberInfoEntity
.
setMobilePhone
(
profile
.
getMobile
());
memberInfoEntity
.
setEmail
(
profile
.
getEmail
());
MemberInfoEntity
result
=
bizMemberInfoService
.
createMemberInfo
(
memberInfoEntity
);
try
{
memberEquityService
.
initMemberEquity
(
result
.
getMemberId
().
longValue
());
}
catch
(
Exception
e
)
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
return
result
;
}
private
MemberInfoEntity
findByMobile
(
String
mobile
)
throws
Exception
{
CheckMemberInfoQueryCondition
condition
=
new
CheckMemberInfoQueryCondition
();
condition
.
setMobilePhone
(
mobile
);
List
<
CheckMemberInfoQueryItem
>
items
=
bizMemberInfoService
.
checkMemberInfoIsExist
(
condition
);
if
(
CollectionUtils
.
isEmpty
(
items
))
{
return
null
;
}
return
bizMemberInfoService
.
getById
(
items
.
get
(
0
).
getMemberId
());
}
private
MemberInfoEntity
findByEmail
(
String
email
)
throws
Exception
{
CheckMemberInfoQueryCondition
condition
=
new
CheckMemberInfoQueryCondition
();
condition
.
setEmail
(
email
);
List
<
CheckMemberInfoQueryItem
>
items
=
bizMemberInfoService
.
checkMemberInfoIsExist
(
condition
);
if
(
CollectionUtils
.
isEmpty
(
items
))
{
return
null
;
}
return
bizMemberInfoService
.
getById
(
items
.
get
(
0
).
getMemberId
());
}
private
String
resolveAccount
(
WecomUserProfile
profile
)
{
if
(
StringUtils
.
isNotBlank
(
profile
.
getMobile
()))
{
return
profile
.
getMobile
();
}
if
(
StringUtils
.
isNotBlank
(
profile
.
getEmail
()))
{
return
profile
.
getEmail
();
}
return
buildWecomAccount
(
profile
);
}
private
String
resolveAvatar
(
String
avatarUrl
)
{
if
(
StringUtils
.
isNotBlank
(
avatarUrl
))
{
return
avatarUrl
;
}
return
fmxParamConfigService
.
getParam
(
"member.default.avatar"
);
}
private
String
buildWecomAccount
(
WecomUserProfile
profile
)
{
String
userId
=
StringUtils
.
defaultIfBlank
(
profile
.
getUserId
(),
profile
.
getOpenUserId
());
if
(
StringUtils
.
isBlank
(
userId
))
{
return
null
;
}
String
corpId
=
profile
.
getCorpId
();
if
(
StringUtils
.
isBlank
(
corpId
))
{
return
WecomConstant
.
AccountPrefix
.
WECOM
+
userId
;
}
return
WecomConstant
.
AccountPrefix
.
WECOM
+
corpId
+
":"
+
userId
;
}
}
src/main/java/cn/com/poc/user/constants/UserLoginConstants.java
View file @
5c402aa7
...
...
@@ -12,6 +12,7 @@ public class UserLoginConstants {
public
final
static
String
MEMBER_PLATFOMR_PW
=
"MEMBER_PLATFOMR_PW"
;
public
final
static
String
MEMBER_PLATFOMR_EMAIL
=
"MEMBER_PLATFOMR_EMAIL"
;
public
final
static
String
MEMBER_PLATFOMR_GOOGLE
=
"MEMBER_PLATFOMR_GOOGLE"
;
public
final
static
String
MEMBER_PLATFOMR_WECOM
=
"MEMBER_PLATFOMR_WECOM"
;
}
...
...
src/main/java/cn/com/poc/user/dto/MemberLoginRequestDto.java
View file @
5c402aa7
...
...
@@ -23,6 +23,11 @@ public class MemberLoginRequestDto {
*/
private
String
authCode
;
/**
* 第三方登录类型
*/
private
String
loginType
;
/**
* 密码(md5)
*/
...
...
@@ -52,6 +57,14 @@ public class MemberLoginRequestDto {
this
.
authCode
=
authCode
;
}
public
String
getLoginType
()
{
return
loginType
;
}
public
void
setLoginType
(
String
loginType
)
{
this
.
loginType
=
loginType
;
}
public
String
getPassword
()
{
return
password
;
}
...
...
src/main/java/cn/com/poc/user/wecom/api/WecomBaseApi.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
api
;
import
org.apache.http.Header
;
import
org.apache.http.HttpHeaders
;
import
org.apache.http.entity.ContentType
;
import
org.apache.http.message.BasicHeader
;
public
interface
WecomBaseApi
{
String
QY_BASE_URI
=
"https://qyapi.weixin.qq.com"
;
String
OPEN_URI
=
"https://open.weixin.qq.com"
;
String
QY_OPEN_URI
=
"https://open.work.weixin.qq.com"
;
Header
JSON_HEADER
=
new
BasicHeader
(
HttpHeaders
.
CONTENT_TYPE
,
ContentType
.
APPLICATION_JSON
.
toString
());
}
src/main/java/cn/com/poc/user/wecom/api/WecomServiceApi.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
api
;
import
cn.com.poc.common.utils.http.LocalHttpClient
;
import
cn.com.poc.user.wecom.domain.WecomLoginInfoResponse
;
import
cn.com.poc.user.wecom.domain.WecomUserInfo3rd
;
import
org.apache.http.client.methods.HttpUriRequest
;
import
org.apache.http.client.methods.RequestBuilder
;
import
org.apache.http.entity.StringEntity
;
import
org.springframework.stereotype.Service
;
import
java.nio.charset.StandardCharsets
;
@Service
public
class
WecomServiceApi
implements
WecomBaseApi
{
public
WecomUserInfo3rd
getUserInfo3rd
(
String
suiteAccessToken
,
String
code
)
{
HttpUriRequest
httpUriRequest
=
RequestBuilder
.
get
()
.
setUri
(
QY_BASE_URI
+
"/cgi-bin/service/getuserinfo3rd"
)
.
addParameter
(
"suite_access_token"
,
suiteAccessToken
)
.
addParameter
(
"code"
,
code
)
.
build
();
return
LocalHttpClient
.
executeJsonResult
(
httpUriRequest
,
WecomUserInfo3rd
.
class
);
}
public
WecomUserInfo3rd
getUserDetail3rd
(
String
suiteAccessToken
,
String
userTicket
)
{
String
jsonData
=
String
.
format
(
"{\"user_ticket\":\"%1$s\"}"
,
userTicket
);
HttpUriRequest
httpUriRequest
=
RequestBuilder
.
post
()
.
setHeader
(
JSON_HEADER
)
.
addParameter
(
"suite_access_token"
,
suiteAccessToken
)
.
setUri
(
QY_BASE_URI
+
"/cgi-bin/service/getuserdetail3rd"
)
.
setEntity
(
new
StringEntity
(
jsonData
,
StandardCharsets
.
UTF_8
))
.
build
();
return
LocalHttpClient
.
executeJsonResult
(
httpUriRequest
,
WecomUserInfo3rd
.
class
);
}
public
WecomLoginInfoResponse
getLoginInfo
(
String
providerAccessToken
,
String
authCode
)
{
String
jsonData
=
String
.
format
(
"{\"auth_code\":\"%1$s\"}"
,
authCode
);
HttpUriRequest
httpUriRequest
=
RequestBuilder
.
post
()
.
setHeader
(
JSON_HEADER
)
.
addParameter
(
"access_token"
,
providerAccessToken
)
.
setUri
(
QY_BASE_URI
+
"/cgi-bin/service/get_login_info"
)
.
setEntity
(
new
StringEntity
(
jsonData
,
StandardCharsets
.
UTF_8
))
.
build
();
return
LocalHttpClient
.
executeJsonResult
(
httpUriRequest
,
WecomLoginInfoResponse
.
class
);
}
}
src/main/java/cn/com/poc/user/wecom/api/WecomTokenApi.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
api
;
import
cn.com.poc.common.utils.http.LocalHttpClient
;
import
cn.com.poc.user.wecom.domain.WecomProviderAccessToken
;
import
cn.com.poc.user.wecom.domain.WecomSuiteAccessToken
;
import
org.apache.http.client.methods.HttpUriRequest
;
import
org.apache.http.client.methods.RequestBuilder
;
import
org.apache.http.entity.StringEntity
;
import
org.springframework.stereotype.Service
;
import
java.nio.charset.StandardCharsets
;
@Service
public
class
WecomTokenApi
implements
WecomBaseApi
{
public
WecomProviderAccessToken
getProviderToken
(
String
corpId
,
String
providerSecret
)
{
String
jsonData
=
String
.
format
(
"{\"corpid\":\"%1$s\",\"provider_secret\":\"%2$s\"}"
,
corpId
,
providerSecret
);
HttpUriRequest
httpUriRequest
=
RequestBuilder
.
post
()
.
setHeader
(
JSON_HEADER
)
.
setUri
(
QY_BASE_URI
+
"/cgi-bin/service/get_provider_token"
)
.
setEntity
(
new
StringEntity
(
jsonData
,
StandardCharsets
.
UTF_8
))
.
build
();
return
LocalHttpClient
.
executeJsonResult
(
httpUriRequest
,
WecomProviderAccessToken
.
class
);
}
public
WecomSuiteAccessToken
getSuiteToken
(
String
suiteId
,
String
suiteSecret
,
String
suiteTicket
)
{
String
jsonData
=
String
.
format
(
"{\"suite_id\":\"%1$s\",\"suite_secret\":\"%2$s\",\"suite_ticket\":\"%3$s\"}"
,
suiteId
,
suiteSecret
,
suiteTicket
);
HttpUriRequest
httpUriRequest
=
RequestBuilder
.
post
()
.
setHeader
(
JSON_HEADER
)
.
setUri
(
QY_BASE_URI
+
"/cgi-bin/service/get_suite_token"
)
.
setEntity
(
new
StringEntity
(
jsonData
,
StandardCharsets
.
UTF_8
))
.
build
();
return
LocalHttpClient
.
executeJsonResult
(
httpUriRequest
,
WecomSuiteAccessToken
.
class
);
}
}
src/main/java/cn/com/poc/user/wecom/constant/WecomConstant.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
constant
;
public
final
class
WecomConstant
{
private
WecomConstant
()
{
}
public
interface
LoginType
{
String
QR_CODE_LOGIN
=
"qr_code_login"
;
String
WEB_PAGE_LOGIN
=
"web_page_login"
;
}
public
interface
RedisKey
{
String
SUITE_TICKET
=
"wecom:suite_ticket"
;
String
SUITE_ACCESS_TOKEN
=
"wecom:suite_access_token"
;
String
PROVIDER_ACCESS_TOKEN
=
"wecom:provider_access_token"
;
}
public
interface
AccountPrefix
{
String
WECOM
=
"wecom:"
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomBaseResult.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
import
java.io.Serializable
;
public
class
WecomBaseResult
implements
Serializable
{
private
static
final
String
SUCCESS_CODE
=
"0"
;
private
String
errcode
;
private
String
errmsg
;
public
String
getErrcode
()
{
return
errcode
;
}
public
void
setErrcode
(
String
errcode
)
{
this
.
errcode
=
errcode
;
}
public
String
getErrmsg
()
{
return
errmsg
;
}
public
void
setErrmsg
(
String
errmsg
)
{
this
.
errmsg
=
errmsg
;
}
public
boolean
isSuccess
()
{
return
errcode
==
null
||
""
.
equals
(
errcode
)
||
SUCCESS_CODE
.
equals
(
errcode
);
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomCorpInfo.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
import
java.io.Serializable
;
public
class
WecomCorpInfo
implements
Serializable
{
private
String
corp_name
;
private
String
corpid
;
private
String
corp_type
;
private
String
corp_square_logo_url
;
public
String
getCorp_name
()
{
return
corp_name
;
}
public
void
setCorp_name
(
String
corp_name
)
{
this
.
corp_name
=
corp_name
;
}
public
String
getCorpid
()
{
return
corpid
;
}
public
void
setCorpid
(
String
corpid
)
{
this
.
corpid
=
corpid
;
}
public
String
getCorp_type
()
{
return
corp_type
;
}
public
void
setCorp_type
(
String
corp_type
)
{
this
.
corp_type
=
corp_type
;
}
public
String
getCorp_square_logo_url
()
{
return
corp_square_logo_url
;
}
public
void
setCorp_square_logo_url
(
String
corp_square_logo_url
)
{
this
.
corp_square_logo_url
=
corp_square_logo_url
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomLoginInfoResponse.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
public
class
WecomLoginInfoResponse
extends
WecomBaseResult
{
private
Integer
usertype
;
private
WecomUserInfo
user_info
;
private
WecomCorpInfo
corp_info
;
private
String
agent
;
private
String
auth_info
;
public
Integer
getUsertype
()
{
return
usertype
;
}
public
void
setUsertype
(
Integer
usertype
)
{
this
.
usertype
=
usertype
;
}
public
WecomUserInfo
getUser_info
()
{
return
user_info
;
}
public
void
setUser_info
(
WecomUserInfo
user_info
)
{
this
.
user_info
=
user_info
;
}
public
WecomCorpInfo
getCorp_info
()
{
return
corp_info
;
}
public
void
setCorp_info
(
WecomCorpInfo
corp_info
)
{
this
.
corp_info
=
corp_info
;
}
public
String
getAgent
()
{
return
agent
;
}
public
void
setAgent
(
String
agent
)
{
this
.
agent
=
agent
;
}
public
String
getAuth_info
()
{
return
auth_info
;
}
public
void
setAuth_info
(
String
auth_info
)
{
this
.
auth_info
=
auth_info
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomLoginUrlDto.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
public
class
WecomLoginUrlDto
{
private
String
url
;
private
String
loginType
;
public
String
getUrl
()
{
return
url
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
String
getLoginType
()
{
return
loginType
;
}
public
void
setLoginType
(
String
loginType
)
{
this
.
loginType
=
loginType
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomProviderAccessToken.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
public
class
WecomProviderAccessToken
extends
WecomBaseResult
{
private
String
provider_access_token
;
private
int
expires_in
;
public
String
getProvider_access_token
()
{
return
provider_access_token
;
}
public
void
setProvider_access_token
(
String
provider_access_token
)
{
this
.
provider_access_token
=
provider_access_token
;
}
public
int
getExpires_in
()
{
return
expires_in
;
}
public
void
setExpires_in
(
int
expires_in
)
{
this
.
expires_in
=
expires_in
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomSuiteAccessToken.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
public
class
WecomSuiteAccessToken
extends
WecomBaseResult
{
private
String
suite_access_token
;
private
int
expires_in
;
public
String
getSuite_access_token
()
{
return
suite_access_token
;
}
public
void
setSuite_access_token
(
String
suite_access_token
)
{
this
.
suite_access_token
=
suite_access_token
;
}
public
int
getExpires_in
()
{
return
expires_in
;
}
public
void
setExpires_in
(
int
expires_in
)
{
this
.
expires_in
=
expires_in
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomUserInfo.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
public
class
WecomUserInfo
extends
WecomBaseResult
{
private
String
userid
;
private
String
name
;
private
String
mobile
;
private
String
email
;
private
String
avatar
;
private
String
open_userid
;
private
String
qr_code
;
public
String
getUserid
()
{
return
userid
;
}
public
void
setUserid
(
String
userid
)
{
this
.
userid
=
userid
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getMobile
()
{
return
mobile
;
}
public
void
setMobile
(
String
mobile
)
{
this
.
mobile
=
mobile
;
}
public
String
getEmail
()
{
return
email
;
}
public
void
setEmail
(
String
email
)
{
this
.
email
=
email
;
}
public
String
getAvatar
()
{
return
avatar
;
}
public
void
setAvatar
(
String
avatar
)
{
this
.
avatar
=
avatar
;
}
public
String
getOpen_userid
()
{
return
open_userid
;
}
public
void
setOpen_userid
(
String
open_userid
)
{
this
.
open_userid
=
open_userid
;
}
public
String
getQr_code
()
{
return
qr_code
;
}
public
void
setQr_code
(
String
qr_code
)
{
this
.
qr_code
=
qr_code
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomUserInfo3rd.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
public
class
WecomUserInfo3rd
extends
WecomBaseResult
{
private
String
CorpId
;
private
String
UserId
;
private
String
DeviceId
;
private
String
user_ticket
;
private
Integer
expires_in
;
private
String
open_userid
;
private
String
external_userid
;
private
String
OpenId
;
private
String
corpid
;
private
String
userid
;
private
String
name
;
private
Integer
gender
;
private
String
avatar
;
private
String
qr_code
;
private
String
mobile
;
private
String
email
;
public
String
getCorpId
()
{
return
CorpId
;
}
public
void
setCorpId
(
String
corpId
)
{
CorpId
=
corpId
;
}
public
String
getUserId
()
{
return
UserId
;
}
public
void
setUserId
(
String
userId
)
{
UserId
=
userId
;
}
public
String
getDeviceId
()
{
return
DeviceId
;
}
public
void
setDeviceId
(
String
deviceId
)
{
DeviceId
=
deviceId
;
}
public
String
getUser_ticket
()
{
return
user_ticket
;
}
public
void
setUser_ticket
(
String
user_ticket
)
{
this
.
user_ticket
=
user_ticket
;
}
public
Integer
getExpires_in
()
{
return
expires_in
;
}
public
void
setExpires_in
(
Integer
expires_in
)
{
this
.
expires_in
=
expires_in
;
}
public
String
getOpen_userid
()
{
return
open_userid
;
}
public
void
setOpen_userid
(
String
open_userid
)
{
this
.
open_userid
=
open_userid
;
}
public
String
getExternal_userid
()
{
return
external_userid
;
}
public
void
setExternal_userid
(
String
external_userid
)
{
this
.
external_userid
=
external_userid
;
}
public
String
getOpenId
()
{
return
OpenId
;
}
public
void
setOpenId
(
String
openId
)
{
OpenId
=
openId
;
}
public
String
getCorpid
()
{
return
corpid
;
}
public
void
setCorpid
(
String
corpid
)
{
this
.
corpid
=
corpid
;
}
public
String
getUserid
()
{
return
userid
;
}
public
void
setUserid
(
String
userid
)
{
this
.
userid
=
userid
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
Integer
getGender
()
{
return
gender
;
}
public
void
setGender
(
Integer
gender
)
{
this
.
gender
=
gender
;
}
public
String
getAvatar
()
{
return
avatar
;
}
public
void
setAvatar
(
String
avatar
)
{
this
.
avatar
=
avatar
;
}
public
String
getQr_code
()
{
return
qr_code
;
}
public
void
setQr_code
(
String
qr_code
)
{
this
.
qr_code
=
qr_code
;
}
public
String
getMobile
()
{
return
mobile
;
}
public
void
setMobile
(
String
mobile
)
{
this
.
mobile
=
mobile
;
}
public
String
getEmail
()
{
return
email
;
}
public
void
setEmail
(
String
email
)
{
this
.
email
=
email
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/WecomUserProfile.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
;
public
class
WecomUserProfile
{
private
String
corpId
;
private
String
userId
;
private
String
openUserId
;
private
String
name
;
private
String
avatarUrl
;
private
String
mobile
;
private
String
email
;
public
String
getCorpId
()
{
return
corpId
;
}
public
void
setCorpId
(
String
corpId
)
{
this
.
corpId
=
corpId
;
}
public
String
getUserId
()
{
return
userId
;
}
public
void
setUserId
(
String
userId
)
{
this
.
userId
=
userId
;
}
public
String
getOpenUserId
()
{
return
openUserId
;
}
public
void
setOpenUserId
(
String
openUserId
)
{
this
.
openUserId
=
openUserId
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getAvatarUrl
()
{
return
avatarUrl
;
}
public
void
setAvatarUrl
(
String
avatarUrl
)
{
this
.
avatarUrl
=
avatarUrl
;
}
public
String
getMobile
()
{
return
mobile
;
}
public
void
setMobile
(
String
mobile
)
{
this
.
mobile
=
mobile
;
}
public
String
getEmail
()
{
return
email
;
}
public
void
setEmail
(
String
email
)
{
this
.
email
=
email
;
}
}
src/main/java/cn/com/poc/user/wecom/domain/properties/WecomProperties.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
domain
.
properties
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
@Component
public
class
WecomProperties
{
@Value
(
"${wecom.corpid:}"
)
private
String
corpId
;
@Value
(
"${wecom.redirect_url:}"
)
private
String
redirectUrl
;
@Value
(
"${wecom.provider_secret:}"
)
private
String
providerSecret
;
@Value
(
"${wecom.suite_id:}"
)
private
String
suiteId
;
@Value
(
"${wecom.suite_secret:}"
)
private
String
suiteSecret
;
@Value
(
"${wecom.token:}"
)
private
String
token
;
@Value
(
"${wecom.encoding_aes_key:}"
)
private
String
encodingAesKey
;
public
String
getCorpId
()
{
return
corpId
;
}
public
String
getRedirectUrl
()
{
return
redirectUrl
;
}
public
String
getProviderSecret
()
{
return
providerSecret
;
}
public
String
getSuiteId
()
{
return
suiteId
;
}
public
String
getSuiteSecret
()
{
return
suiteSecret
;
}
public
String
getToken
()
{
return
token
;
}
public
String
getEncodingAesKey
()
{
return
encodingAesKey
;
}
}
src/main/java/cn/com/poc/user/wecom/rest/WecomCallbackRest.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
rest
;
import
cn.com.yict.framemax.core.rest.BaseRest
;
import
cn.com.yict.framemax.web.permission.Access
;
import
cn.com.yict.framemax.web.permission.Permission
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
@Permission
(
Access
.
Anonymous
)
public
interface
WecomCallbackRest
extends
BaseRest
{
void
commandEvent
(
HttpServletRequest
request
,
HttpServletResponse
response
,
@RequestParam
(
value
=
"msg_signature"
)
String
msgSignature
,
@RequestParam
(
value
=
"timestamp"
)
String
timestamp
,
@RequestParam
(
value
=
"nonce"
)
String
nonce
,
@RequestParam
(
value
=
"echostr"
,
required
=
false
)
String
data
)
throws
Exception
;
}
src/main/java/cn/com/poc/user/wecom/rest/WecomLoginRest.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
rest
;
import
cn.com.poc.user.dto.MemberLoginResponseDto
;
import
cn.com.poc.user.wecom.domain.WecomLoginUrlDto
;
import
cn.com.yict.framemax.core.rest.BaseRest
;
import
cn.com.yict.framemax.web.permission.Access
;
import
cn.com.yict.framemax.web.permission.Permission
;
import
org.springframework.web.bind.annotation.RequestParam
;
@Permission
(
Access
.
Anonymous
)
public
interface
WecomLoginRest
extends
BaseRest
{
WecomLoginUrlDto
getOauthUrl
(
@RequestParam
(
required
=
false
,
name
=
"requesturl"
)
String
requestUrl
,
@RequestParam
(
required
=
false
,
name
=
"scope"
)
String
scope
,
@RequestParam
(
required
=
false
,
name
=
"state"
)
String
state
)
throws
Exception
;
WecomLoginUrlDto
getQrConnectUrl
(
@RequestParam
(
required
=
false
,
name
=
"requesturl"
)
String
requestUrl
,
@RequestParam
(
required
=
false
,
name
=
"userType"
)
String
userType
,
@RequestParam
(
required
=
false
,
name
=
"state"
)
String
state
)
throws
Exception
;
MemberLoginResponseDto
toLogin
(
@RequestParam
String
code
,
@RequestParam
String
loginType
)
throws
Exception
;
}
src/main/java/cn/com/poc/user/wecom/rest/impl/WecomCallbackRestImpl.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
rest
.
impl
;
import
cn.com.poc.common.service.RedisService
;
import
cn.com.poc.common.utils.StringUtils
;
import
cn.com.poc.user.wecom.constant.WecomConstant
;
import
cn.com.poc.user.wecom.domain.properties.WecomProperties
;
import
cn.com.poc.user.wecom.rest.WecomCallbackRest
;
import
cn.com.poc.user.wecom.util.WXBizMsgCrypt
;
import
org.json.JSONObject
;
import
org.json.XML
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.BufferedReader
;
import
java.io.PrintWriter
;
@Component
public
class
WecomCallbackRestImpl
implements
WecomCallbackRest
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
WecomCallbackRestImpl
.
class
);
@Resource
private
WecomProperties
wecomProperties
;
@Resource
private
RedisService
redisService
;
@Override
public
void
commandEvent
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
msgSignature
,
String
timestamp
,
String
nonce
,
String
data
)
throws
Exception
{
String
method
=
request
.
getMethod
();
if
(
"GET"
.
equalsIgnoreCase
(
method
))
{
handleVerify
(
response
,
msgSignature
,
timestamp
,
nonce
,
data
);
return
;
}
if
(
"POST"
.
equalsIgnoreCase
(
method
))
{
handleSuiteTicket
(
request
,
response
,
msgSignature
,
timestamp
,
nonce
);
}
}
private
void
handleVerify
(
HttpServletResponse
response
,
String
msgSignature
,
String
timestamp
,
String
nonce
,
String
data
)
throws
Exception
{
PrintWriter
writer
=
response
.
getWriter
();
WXBizMsgCrypt
wxcpt
=
buildSuiteCrypt
();
String
echoStr
=
wxcpt
.
VerifyURL
(
msgSignature
,
timestamp
,
nonce
,
data
);
writer
.
print
(
echoStr
);
writer
.
flush
();
}
private
void
handleSuiteTicket
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
msgSignature
,
String
timestamp
,
String
nonce
)
throws
Exception
{
StringBuilder
body
=
new
StringBuilder
();
BufferedReader
reader
=
request
.
getReader
();
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
body
.
append
(
line
);
}
WXBizMsgCrypt
wxcpt
=
buildSuiteCrypt
();
String
decryptedXml
=
wxcpt
.
DecryptMsg
(
msgSignature
,
timestamp
,
nonce
,
body
.
toString
());
logger
.
info
(
"wecom suite callback payload: {}"
,
decryptedXml
);
JSONObject
jsonObject
=
XML
.
toJSONObject
(
decryptedXml
).
getJSONObject
(
"xml"
);
String
infoType
=
jsonObject
.
optString
(
"InfoType"
);
if
(
"suite_ticket"
.
equalsIgnoreCase
(
infoType
))
{
String
suiteId
=
jsonObject
.
optString
(
"SuiteId"
);
String
suiteTicket
=
jsonObject
.
optString
(
"SuiteTicket"
);
if
(
StringUtils
.
isNotBlank
(
suiteId
)
&&
StringUtils
.
isNotBlank
(
suiteTicket
))
{
String
redisKey
=
WecomConstant
.
RedisKey
.
SUITE_TICKET
+
":"
+
suiteId
;
redisService
.
set
(
redisKey
,
suiteTicket
);
logger
.
info
(
"stored suite_ticket for suiteId {}"
,
suiteId
);
}
}
PrintWriter
writer
=
response
.
getWriter
();
writer
.
print
(
"success"
);
writer
.
flush
();
}
private
WXBizMsgCrypt
buildSuiteCrypt
()
throws
Exception
{
return
new
WXBizMsgCrypt
(
wecomProperties
.
getToken
(),
wecomProperties
.
getEncodingAesKey
(),
wecomProperties
.
getSuiteId
());
}
}
src/main/java/cn/com/poc/user/wecom/rest/impl/WecomLoginRestImpl.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
rest
.
impl
;
import
cn.com.poc.common.utils.Assert
;
import
cn.com.poc.common.utils.StringUtils
;
import
cn.com.poc.support.security.oauth.constants.OauthConstants
;
import
cn.com.poc.user.builder.LoginChannelBuilder
;
import
cn.com.poc.user.constants.UserLoginConstants
;
import
cn.com.poc.user.dto.MemberLoginRequestDto
;
import
cn.com.poc.user.dto.MemberLoginResponseDto
;
import
cn.com.poc.user.entity.MemberInfoEntity
;
import
cn.com.poc.user.wecom.constant.WecomConstant
;
import
cn.com.poc.user.wecom.domain.WecomLoginUrlDto
;
import
cn.com.poc.user.wecom.domain.properties.WecomProperties
;
import
cn.com.poc.user.wecom.rest.WecomLoginRest
;
import
cn.com.poc.user.wecom.service.WecomComponentService
;
import
cn.com.yict.framemax.core.i18n.I18nMessageException
;
import
cn.com.yict.framemax.security.oauth.OauthAccesstokenManager
;
import
cn.com.yict.framemax.security.oauth.entity.OauthResultEntity
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
@Component
public
class
WecomLoginRestImpl
implements
WecomLoginRest
{
@Resource
private
WecomProperties
wecomProperties
;
@Resource
private
WecomComponentService
wecomComponentService
;
@Resource
private
LoginChannelBuilder
loginChannelBuilder
;
@Resource
private
OauthAccesstokenManager
tokenManager
;
@Override
public
WecomLoginUrlDto
getOauthUrl
(
String
requestUrl
,
String
scope
,
String
state
)
throws
Exception
{
String
redirectUrl
=
StringUtils
.
isBlank
(
requestUrl
)
?
wecomProperties
.
getRedirectUrl
()
:
requestUrl
;
String
suiteId
=
wecomProperties
.
getSuiteId
();
Assert
.
notBlank
(
redirectUrl
,
"redirectUrl"
);
Assert
.
notBlank
(
suiteId
,
"suiteId"
);
String
scopeValue
=
StringUtils
.
defaultIfBlank
(
scope
,
"snsapi_privateinfo"
);
String
stateValue
=
StringUtils
.
defaultIfBlank
(
state
,
WecomConstant
.
LoginType
.
WEB_PAGE_LOGIN
);
String
oauthUrl
=
wecomComponentService
.
oauth2Authorize
(
suiteId
,
redirectUrl
,
"code"
,
scopeValue
,
stateValue
);
WecomLoginUrlDto
result
=
new
WecomLoginUrlDto
();
result
.
setLoginType
(
WecomConstant
.
LoginType
.
WEB_PAGE_LOGIN
);
result
.
setUrl
(
oauthUrl
);
return
result
;
}
@Override
public
WecomLoginUrlDto
getQrConnectUrl
(
String
requestUrl
,
String
userType
,
String
state
)
throws
Exception
{
String
redirectUrl
=
StringUtils
.
isBlank
(
requestUrl
)
?
wecomProperties
.
getRedirectUrl
()
:
requestUrl
;
String
corpId
=
wecomProperties
.
getCorpId
();
Assert
.
notBlank
(
redirectUrl
,
"redirectUrl"
);
Assert
.
notBlank
(
corpId
,
"corpId"
);
String
stateValue
=
StringUtils
.
defaultIfBlank
(
state
,
WecomConstant
.
LoginType
.
QR_CODE_LOGIN
);
String
qrUrl
=
wecomComponentService
.
connectQrconnect
(
corpId
,
redirectUrl
,
userType
,
stateValue
);
WecomLoginUrlDto
result
=
new
WecomLoginUrlDto
();
result
.
setLoginType
(
WecomConstant
.
LoginType
.
QR_CODE_LOGIN
);
result
.
setUrl
(
qrUrl
);
return
result
;
}
@Override
public
MemberLoginResponseDto
toLogin
(
String
code
,
String
loginType
)
throws
Exception
{
Assert
.
notBlank
(
code
,
"code"
);
Assert
.
notBlank
(
loginType
,
"loginType"
);
MemberLoginRequestDto
request
=
new
MemberLoginRequestDto
();
request
.
setLoginChannel
(
UserLoginConstants
.
LoginType
.
MEMBER_PLATFOMR_WECOM
);
request
.
setAuthCode
(
code
);
request
.
setLoginType
(
loginType
);
MemberInfoEntity
memberInfoEntity
=
(
MemberInfoEntity
)
loginChannelBuilder
.
getService
(
request
.
getLoginChannel
())
.
doLogin
(
request
);
if
(
memberInfoEntity
==
null
)
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
OauthResultEntity
auth
=
tokenManager
.
auth
(
OauthConstants
.
TypePrefix
.
MEMBER_DOMAIN
+
memberInfoEntity
.
getMemberId
(),
null
,
null
);
MemberLoginResponseDto
response
=
new
MemberLoginResponseDto
();
response
.
setMemberId
(
memberInfoEntity
.
getMemberId
());
response
.
setNickName
(
memberInfoEntity
.
getNickName
());
response
.
setAvatarUrl
(
memberInfoEntity
.
getAvatarUrl
());
response
.
setMobilePhone
(
memberInfoEntity
.
getMobilePhone
());
response
.
setToken
(
auth
.
getToken
());
return
response
;
}
}
src/main/java/cn/com/poc/user/wecom/service/WecomComponentService.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
service
;
import
cn.com.poc.common.utils.StringUtils
;
import
cn.com.poc.user.wecom.api.WecomBaseApi
;
import
org.apache.log4j.Logger
;
import
org.springframework.stereotype.Service
;
import
java.io.UnsupportedEncodingException
;
import
java.net.URLEncoder
;
@Service
public
class
WecomComponentService
implements
WecomBaseApi
{
private
final
Logger
logger
=
Logger
.
getLogger
(
this
.
getClass
());
public
String
oauth2Authorize
(
String
appid
,
String
redirectUri
,
String
responseType
,
String
scope
,
String
state
)
{
try
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
OPEN_URI
+
"/connect/oauth2/authorize?"
)
.
append
(
"appid="
).
append
(
appid
)
.
append
(
"&redirect_uri="
).
append
(
URLEncoder
.
encode
(
redirectUri
,
"utf-8"
))
.
append
(
"&response_type="
).
append
(
responseType
)
.
append
(
"&scope="
).
append
(
scope
)
.
append
(
"&state="
).
append
(
state
)
.
append
(
"#wechat_redirect"
);
return
sb
.
toString
();
}
catch
(
UnsupportedEncodingException
e
)
{
logger
.
error
(
"oauth2Authorize error"
,
e
);
return
null
;
}
}
public
String
connectQrconnect
(
String
appid
,
String
redirectUri
,
String
userType
,
String
state
)
{
try
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
QY_OPEN_URI
+
"/wwopen/sso/3rd_qrConnect?"
)
.
append
(
"appid="
).
append
(
appid
)
.
append
(
"&redirect_uri="
).
append
(
URLEncoder
.
encode
(
redirectUri
,
"utf-8"
))
.
append
(
"&usertype="
).
append
(
StringUtils
.
defaultString
(
userType
,
"member"
))
.
append
(
"&state="
).
append
(
state
==
null
?
""
:
state
);
return
sb
.
toString
();
}
catch
(
UnsupportedEncodingException
e
)
{
logger
.
error
(
"connectQrconnect error"
,
e
);
return
null
;
}
}
}
src/main/java/cn/com/poc/user/wecom/service/WecomLoginService.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
service
;
import
cn.com.poc.common.utils.Assert
;
import
cn.com.poc.common.utils.StringUtils
;
import
cn.com.poc.user.wecom.constant.WecomConstant
;
import
cn.com.poc.user.wecom.domain.WecomCorpInfo
;
import
cn.com.poc.user.wecom.domain.WecomLoginInfoResponse
;
import
cn.com.poc.user.wecom.domain.WecomUserInfo
;
import
cn.com.poc.user.wecom.domain.WecomUserInfo3rd
;
import
cn.com.poc.user.wecom.domain.WecomUserProfile
;
import
cn.com.yict.framemax.core.i18n.I18nMessageException
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
@Service
public
class
WecomLoginService
{
@Resource
private
WecomTokenService
wecomTokenService
;
@Resource
private
WecomUserService
wecomUserService
;
public
WecomUserProfile
getUserProfile
(
String
code
,
String
loginType
)
{
Assert
.
notBlank
(
code
,
"code"
);
Assert
.
notBlank
(
loginType
,
"loginType"
);
if
(
WecomConstant
.
LoginType
.
QR_CODE_LOGIN
.
equals
(
loginType
))
{
return
getProfileByQrCode
(
code
);
}
if
(
WecomConstant
.
LoginType
.
WEB_PAGE_LOGIN
.
equals
(
loginType
))
{
return
getProfileByWebPage
(
code
);
}
throw
new
I18nMessageException
(
"exception/system.error"
);
}
private
WecomUserProfile
getProfileByQrCode
(
String
code
)
{
String
providerToken
=
wecomTokenService
.
getProviderToken
();
WecomLoginInfoResponse
loginInfo
=
wecomUserService
.
getLoginInfo
(
providerToken
,
code
);
WecomUserInfo
userInfo
=
loginInfo
.
getUser_info
();
WecomCorpInfo
corpInfo
=
loginInfo
.
getCorp_info
();
if
(
userInfo
==
null
||
corpInfo
==
null
)
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
WecomUserProfile
profile
=
new
WecomUserProfile
();
profile
.
setCorpId
(
corpInfo
.
getCorpid
());
profile
.
setUserId
(
userInfo
.
getUserid
());
profile
.
setOpenUserId
(
userInfo
.
getOpen_userid
());
profile
.
setName
(
userInfo
.
getName
());
profile
.
setAvatarUrl
(
userInfo
.
getAvatar
());
profile
.
setMobile
(
userInfo
.
getMobile
());
profile
.
setEmail
(
userInfo
.
getEmail
());
return
profile
;
}
private
WecomUserProfile
getProfileByWebPage
(
String
code
)
{
String
suiteToken
=
wecomTokenService
.
getSuiteToken
();
WecomUserInfo3rd
userInfo
=
wecomUserService
.
getUserInfo3rd
(
suiteToken
,
code
);
if
(
StringUtils
.
isBlank
(
userInfo
.
getUser_ticket
()))
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
WecomUserInfo3rd
userDetail
=
wecomUserService
.
getUserDetail3rd
(
suiteToken
,
userInfo
.
getUser_ticket
());
WecomUserProfile
profile
=
new
WecomUserProfile
();
profile
.
setCorpId
(
resolveCorpId
(
userInfo
,
userDetail
));
profile
.
setUserId
(
resolveUserId
(
userInfo
,
userDetail
));
profile
.
setOpenUserId
(
resolveOpenUserId
(
userInfo
,
userDetail
));
profile
.
setName
(
StringUtils
.
defaultIfBlank
(
userDetail
.
getName
(),
userInfo
.
getName
()));
profile
.
setAvatarUrl
(
StringUtils
.
defaultIfBlank
(
userDetail
.
getAvatar
(),
userInfo
.
getAvatar
()));
profile
.
setMobile
(
StringUtils
.
defaultIfBlank
(
userDetail
.
getMobile
(),
userInfo
.
getMobile
()));
profile
.
setEmail
(
StringUtils
.
defaultIfBlank
(
userDetail
.
getEmail
(),
userInfo
.
getEmail
()));
return
profile
;
}
private
String
resolveCorpId
(
WecomUserInfo3rd
userInfo
,
WecomUserInfo3rd
userDetail
)
{
return
StringUtils
.
defaultIfBlank
(
StringUtils
.
defaultIfBlank
(
userDetail
.
getCorpid
(),
userInfo
.
getCorpid
()),
userInfo
.
getCorpId
());
}
private
String
resolveUserId
(
WecomUserInfo3rd
userInfo
,
WecomUserInfo3rd
userDetail
)
{
return
StringUtils
.
defaultIfBlank
(
StringUtils
.
defaultIfBlank
(
userDetail
.
getUserid
(),
userInfo
.
getUserid
()),
userInfo
.
getUserId
());
}
private
String
resolveOpenUserId
(
WecomUserInfo3rd
userInfo
,
WecomUserInfo3rd
userDetail
)
{
return
StringUtils
.
defaultIfBlank
(
StringUtils
.
defaultIfBlank
(
userDetail
.
getOpen_userid
(),
userInfo
.
getOpen_userid
()),
userInfo
.
getOpenId
());
}
}
src/main/java/cn/com/poc/user/wecom/service/WecomTokenService.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
service
;
import
cn.com.poc.common.service.RedisService
;
import
cn.com.poc.common.utils.StringUtils
;
import
cn.com.poc.user.wecom.api.WecomTokenApi
;
import
cn.com.poc.user.wecom.constant.WecomConstant
;
import
cn.com.poc.user.wecom.domain.WecomProviderAccessToken
;
import
cn.com.poc.user.wecom.domain.WecomSuiteAccessToken
;
import
cn.com.poc.user.wecom.domain.properties.WecomProperties
;
import
cn.com.yict.framemax.core.i18n.I18nMessageException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
@Service
public
class
WecomTokenService
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
WecomTokenService
.
class
);
@Resource
private
WecomTokenApi
wecomTokenApi
;
@Resource
private
RedisService
redisService
;
@Resource
private
WecomProperties
wecomProperties
;
public
String
getProviderToken
()
{
String
corpId
=
wecomProperties
.
getCorpId
();
String
providerSecret
=
wecomProperties
.
getProviderSecret
();
if
(
StringUtils
.
isBlank
(
corpId
)
||
StringUtils
.
isBlank
(
providerSecret
))
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
String
tokenKey
=
WecomConstant
.
RedisKey
.
PROVIDER_ACCESS_TOKEN
+
":"
+
corpId
;
String
cachedToken
=
redisService
.
get
(
tokenKey
,
String
.
class
);
if
(
StringUtils
.
isNotBlank
(
cachedToken
))
{
return
cachedToken
;
}
WecomProviderAccessToken
token
=
wecomTokenApi
.
getProviderToken
(
corpId
,
providerSecret
);
if
(
token
!=
null
&&
token
.
isSuccess
())
{
redisService
.
set
(
tokenKey
,
token
.
getProvider_access_token
(),
token
.
getExpires_in
());
return
token
.
getProvider_access_token
();
}
logger
.
error
(
"wecom provider token error: {}"
,
token
==
null
?
"null response"
:
token
.
getErrmsg
());
throw
new
I18nMessageException
(
"exception/system.error"
);
}
public
String
getSuiteToken
()
{
String
suiteId
=
wecomProperties
.
getSuiteId
();
String
suiteSecret
=
wecomProperties
.
getSuiteSecret
();
if
(
StringUtils
.
isBlank
(
suiteId
)
||
StringUtils
.
isBlank
(
suiteSecret
))
{
throw
new
I18nMessageException
(
"exception/system.error"
);
}
String
tokenKey
=
WecomConstant
.
RedisKey
.
SUITE_ACCESS_TOKEN
+
":"
+
suiteId
;
String
cachedToken
=
redisService
.
get
(
tokenKey
,
String
.
class
);
if
(
StringUtils
.
isNotBlank
(
cachedToken
))
{
return
cachedToken
;
}
String
ticketKey
=
WecomConstant
.
RedisKey
.
SUITE_TICKET
+
":"
+
suiteId
;
String
suiteTicket
=
redisService
.
get
(
ticketKey
,
String
.
class
);
if
(
StringUtils
.
isBlank
(
suiteTicket
))
{
logger
.
error
(
"wecom suite ticket missing for suiteId {}"
,
suiteId
);
throw
new
I18nMessageException
(
"exception/system.error"
);
}
WecomSuiteAccessToken
token
=
wecomTokenApi
.
getSuiteToken
(
suiteId
,
suiteSecret
,
suiteTicket
);
if
(
token
!=
null
&&
token
.
isSuccess
())
{
redisService
.
set
(
tokenKey
,
token
.
getSuite_access_token
(),
token
.
getExpires_in
());
return
token
.
getSuite_access_token
();
}
logger
.
error
(
"wecom suite token error: {}"
,
token
==
null
?
"null response"
:
token
.
getErrmsg
());
throw
new
I18nMessageException
(
"exception/system.error"
);
}
}
src/main/java/cn/com/poc/user/wecom/service/WecomUserService.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
service
;
import
cn.com.poc.user.wecom.api.WecomServiceApi
;
import
cn.com.poc.user.wecom.domain.WecomLoginInfoResponse
;
import
cn.com.poc.user.wecom.domain.WecomUserInfo3rd
;
import
cn.com.yict.framemax.core.i18n.I18nMessageException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
@Service
public
class
WecomUserService
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
WecomUserService
.
class
);
@Resource
private
WecomServiceApi
wecomServiceApi
;
public
WecomLoginInfoResponse
getLoginInfo
(
String
providerAccessToken
,
String
authCode
)
{
WecomLoginInfoResponse
response
=
wecomServiceApi
.
getLoginInfo
(
providerAccessToken
,
authCode
);
if
(
response
!=
null
&&
response
.
isSuccess
())
{
return
response
;
}
logger
.
error
(
"wecom login info error: {}"
,
response
==
null
?
"null response"
:
response
.
getErrmsg
());
throw
new
I18nMessageException
(
"exception/system.error"
);
}
public
WecomUserInfo3rd
getUserInfo3rd
(
String
suiteAccessToken
,
String
code
)
{
WecomUserInfo3rd
response
=
wecomServiceApi
.
getUserInfo3rd
(
suiteAccessToken
,
code
);
if
(
response
!=
null
&&
response
.
isSuccess
())
{
return
response
;
}
logger
.
error
(
"wecom user info error: {}"
,
response
==
null
?
"null response"
:
response
.
getErrmsg
());
throw
new
I18nMessageException
(
"exception/system.error"
);
}
public
WecomUserInfo3rd
getUserDetail3rd
(
String
suiteAccessToken
,
String
userTicket
)
{
WecomUserInfo3rd
response
=
wecomServiceApi
.
getUserDetail3rd
(
suiteAccessToken
,
userTicket
);
if
(
response
!=
null
&&
response
.
isSuccess
())
{
return
response
;
}
logger
.
error
(
"wecom user detail error: {}"
,
response
==
null
?
"null response"
:
response
.
getErrmsg
());
throw
new
I18nMessageException
(
"exception/system.error"
);
}
}
src/main/java/cn/com/poc/user/wecom/util/AesException.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
util
;
/**
* 异常描述
*/
@SuppressWarnings
(
"serial"
)
public
class
AesException
extends
Exception
{
public
static
final
int
OK
=
0
;
public
static
final
int
ValidateSignatureError
=
-
40001
;
public
static
final
int
ParseXmlError
=
-
40002
;
public
static
final
int
ComputeSignatureError
=
-
40003
;
public
static
final
int
IllegalAesKey
=
-
40004
;
public
static
final
int
ValidateCorpidError
=
-
40005
;
public
static
final
int
EncryptAESError
=
-
40006
;
public
static
final
int
DecryptAESError
=
-
40007
;
public
static
final
int
IllegalBuffer
=
-
40008
;
private
int
code
;
public
int
getCode
()
{
return
code
;
}
public
AesException
(
int
code
)
{
super
(
getMessage
(
code
));
this
.
code
=
code
;
}
private
static
String
getMessage
(
int
code
)
{
switch
(
code
)
{
case
ValidateSignatureError:
return
"签名验证错误"
;
case
ParseXmlError:
return
"xml解析失败"
;
case
ComputeSignatureError:
return
"sha加密生成签名失败"
;
case
IllegalAesKey:
return
"SymmetricKey非法"
;
case
ValidateCorpidError:
return
"corpid校验失败"
;
case
EncryptAESError:
return
"aes加密失败"
;
case
DecryptAESError:
return
"aes解密失败"
;
case
IllegalBuffer:
return
"解密后得到的buffer非法"
;
default
:
return
"未知错误"
;
}
}
}
src/main/java/cn/com/poc/user/wecom/util/ByteGroup.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
util
;
import
java.util.ArrayList
;
/**
* 用于byte[]数组不断加入byte[]数组
*/
class
ByteGroup
{
ArrayList
<
Byte
>
byteContainer
=
new
ArrayList
<
Byte
>();
public
byte
[]
toBytes
()
{
byte
[]
bytes
=
new
byte
[
byteContainer
.
size
()];
for
(
int
i
=
0
;
i
<
byteContainer
.
size
();
i
++)
{
bytes
[
i
]
=
byteContainer
.
get
(
i
);
}
return
bytes
;
}
public
ByteGroup
addBytes
(
byte
[]
bytes
)
{
for
(
byte
b
:
bytes
)
{
byteContainer
.
add
(
b
);
}
return
this
;
}
public
int
size
()
{
return
byteContainer
.
size
();
}
}
src/main/java/cn/com/poc/user/wecom/util/PKCS7Encoder.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
util
;
import
java.nio.charset.Charset
;
import
java.util.Arrays
;
/**
* 提供基于PKCS7算法的加解密接口
*/
class
PKCS7Encoder
{
static
Charset
CHARSET
=
Charset
.
forName
(
"utf-8"
);
static
int
BLOCK_SIZE
=
32
;
/**
* 获得对明文进行补位填充的字节.
*
* @param count 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
static
byte
[]
encode
(
int
count
)
{
// 计算需要填充的位数
int
amountToPad
=
BLOCK_SIZE
-
(
count
%
BLOCK_SIZE
);
if
(
amountToPad
==
0
)
{
amountToPad
=
BLOCK_SIZE
;
}
// 获得补位所用的字符
char
padChr
=
chr
(
amountToPad
);
StringBuilder
tmp
=
new
StringBuilder
();
for
(
int
index
=
0
;
index
<
amountToPad
;
index
++)
{
tmp
.
append
(
padChr
);
}
return
tmp
.
toString
().
getBytes
(
CHARSET
);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted 解密后的明文
* @return 删除补位字符后的明文
*/
static
byte
[]
decode
(
byte
[]
decrypted
)
{
int
pad
=
decrypted
[
decrypted
.
length
-
1
];
if
(
pad
<
1
||
pad
>
32
)
{
pad
=
0
;
}
return
Arrays
.
copyOfRange
(
decrypted
,
0
,
decrypted
.
length
-
pad
);
}
static
char
chr
(
int
a
)
{
byte
target
=
(
byte
)
(
a
&
0xFF
);
return
(
char
)
target
;
}
}
src/main/java/cn/com/poc/user/wecom/util/SHA1.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
util
;
import
java.security.MessageDigest
;
import
java.util.Arrays
;
class
SHA1
{
/**
* 用SHA1算法生成安全签名
*
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @param encrypt 密文
* @return 安全签名
* @throws AesException
*/
public
static
String
getSHA1
(
String
token
,
String
timestamp
,
String
nonce
,
String
encrypt
)
throws
AesException
{
try
{
String
[]
array
=
new
String
[]{
token
,
timestamp
,
nonce
,
encrypt
};
StringBuilder
sb
=
new
StringBuilder
();
Arrays
.
sort
(
array
);
for
(
String
a
:
array
)
{
sb
.
append
(
a
);
}
String
str
=
sb
.
toString
();
MessageDigest
md
=
MessageDigest
.
getInstance
(
"SHA-1"
);
md
.
update
(
str
.
getBytes
());
byte
[]
digest
=
md
.
digest
();
StringBuilder
hexstr
=
new
StringBuilder
();
String
shaHex
;
for
(
byte
b
:
digest
)
{
shaHex
=
Integer
.
toHexString
(
b
&
0xFF
);
if
(
shaHex
.
length
()
<
2
)
{
hexstr
.
append
(
0
);
}
hexstr
.
append
(
shaHex
);
}
return
hexstr
.
toString
();
}
catch
(
Exception
e
)
{
throw
new
AesException
(
AesException
.
ComputeSignatureError
);
}
}
}
src/main/java/cn/com/poc/user/wecom/util/WXBizMsgCrypt.java
0 → 100644
View file @
5c402aa7
/**
* 对企业微信发送给企业后台的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
package
cn
.
com
.
poc
.
user
.
wecom
.
util
;
import
org.apache.commons.codec.binary.Base64
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.crypto.Cipher
;
import
javax.crypto.spec.IvParameterSpec
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.nio.charset.Charset
;
import
java.util.Arrays
;
import
java.util.Random
;
/**
* 提供接收和推送给企业微信消息的加解密接口(UTF8编码的字符串).
*/
public
class
WXBizMsgCrypt
{
static
Charset
CHARSET
=
Charset
.
forName
(
"utf-8"
);
Base64
base64
=
new
Base64
();
byte
[]
aesKey
;
String
token
;
String
receiveid
;
private
Logger
logger
=
LoggerFactory
.
getLogger
(
this
.
getClass
());
/**
* 构造函数
*
* @param token 企业微信后台,开发者设置的token
* @param encodingAesKey 企业微信后台,开发者设置的EncodingAESKey
* @param receiveid 不同场景含义不同,详见文档
* @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
*/
public
WXBizMsgCrypt
(
String
token
,
String
encodingAesKey
,
String
receiveid
)
throws
AesException
{
if
(
encodingAesKey
.
length
()
!=
43
)
{
throw
new
AesException
(
AesException
.
IllegalAesKey
);
}
this
.
token
=
token
;
this
.
receiveid
=
receiveid
;
aesKey
=
Base64
.
decodeBase64
(
encodingAesKey
+
"="
);
}
byte
[]
getNetworkBytesOrder
(
int
sourceNumber
)
{
byte
[]
orderBytes
=
new
byte
[
4
];
orderBytes
[
3
]
=
(
byte
)
(
sourceNumber
&
0xFF
);
orderBytes
[
2
]
=
(
byte
)
(
sourceNumber
>>
8
&
0xFF
);
orderBytes
[
1
]
=
(
byte
)
(
sourceNumber
>>
16
&
0xFF
);
orderBytes
[
0
]
=
(
byte
)
(
sourceNumber
>>
24
&
0xFF
);
return
orderBytes
;
}
int
recoverNetworkBytesOrder
(
byte
[]
orderBytes
)
{
int
sourceNumber
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
sourceNumber
<<=
8
;
sourceNumber
|=
orderBytes
[
i
]
&
0xff
;
}
return
sourceNumber
;
}
String
getRandomStr
()
{
String
base
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
;
Random
random
=
new
Random
();
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
int
number
=
random
.
nextInt
(
base
.
length
());
sb
.
append
(
base
.
charAt
(
number
));
}
return
sb
.
toString
();
}
String
encrypt
(
String
randomStr
,
String
text
)
throws
AesException
{
ByteGroup
byteCollector
=
new
ByteGroup
();
byte
[]
randomStrBytes
=
randomStr
.
getBytes
(
CHARSET
);
byte
[]
textBytes
=
text
.
getBytes
(
CHARSET
);
byte
[]
networkBytesOrder
=
getNetworkBytesOrder
(
textBytes
.
length
);
byte
[]
receiveidBytes
=
receiveid
.
getBytes
(
CHARSET
);
byteCollector
.
addBytes
(
randomStrBytes
);
byteCollector
.
addBytes
(
networkBytesOrder
);
byteCollector
.
addBytes
(
textBytes
);
byteCollector
.
addBytes
(
receiveidBytes
);
byte
[]
padBytes
=
PKCS7Encoder
.
encode
(
byteCollector
.
size
());
byteCollector
.
addBytes
(
padBytes
);
byte
[]
unencrypted
=
byteCollector
.
toBytes
();
try
{
Cipher
cipher
=
Cipher
.
getInstance
(
"AES/CBC/NoPadding"
);
SecretKeySpec
keySpec
=
new
SecretKeySpec
(
aesKey
,
"AES"
);
IvParameterSpec
iv
=
new
IvParameterSpec
(
aesKey
,
0
,
16
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
keySpec
,
iv
);
byte
[]
encrypted
=
cipher
.
doFinal
(
unencrypted
);
return
base64
.
encodeToString
(
encrypted
);
}
catch
(
Exception
e
)
{
throw
new
AesException
(
AesException
.
EncryptAESError
);
}
}
String
decrypt
(
String
text
)
throws
AesException
{
byte
[]
original
;
try
{
Cipher
cipher
=
Cipher
.
getInstance
(
"AES/CBC/NoPadding"
);
SecretKeySpec
key_spec
=
new
SecretKeySpec
(
aesKey
,
"AES"
);
IvParameterSpec
iv
=
new
IvParameterSpec
(
Arrays
.
copyOfRange
(
aesKey
,
0
,
16
));
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
key_spec
,
iv
);
byte
[]
encrypted
=
Base64
.
decodeBase64
(
text
);
original
=
cipher
.
doFinal
(
encrypted
);
}
catch
(
Exception
e
)
{
throw
new
AesException
(
AesException
.
DecryptAESError
);
}
String
xmlContent
;
String
from_receiveid
;
try
{
byte
[]
bytes
=
PKCS7Encoder
.
decode
(
original
);
byte
[]
networkOrder
=
Arrays
.
copyOfRange
(
bytes
,
16
,
20
);
int
xmlLength
=
recoverNetworkBytesOrder
(
networkOrder
);
xmlContent
=
new
String
(
Arrays
.
copyOfRange
(
bytes
,
20
,
20
+
xmlLength
),
CHARSET
);
from_receiveid
=
new
String
(
Arrays
.
copyOfRange
(
bytes
,
20
+
xmlLength
,
bytes
.
length
),
CHARSET
);
}
catch
(
Exception
e
)
{
throw
new
AesException
(
AesException
.
IllegalBuffer
);
}
logger
.
info
(
"XMLCONTENT:{}"
,
xmlContent
);
if
(!
from_receiveid
.
equals
(
receiveid
))
{
logger
.
info
(
"from_receiveid:{},receiveid{}"
,
from_receiveid
,
receiveid
);
throw
new
AesException
(
AesException
.
ValidateCorpidError
);
}
return
xmlContent
;
}
/**
* 将企业微信回复用户的消息加密打包.
*/
public
String
EncryptMsg
(
String
replyMsg
,
String
timeStamp
,
String
nonce
)
throws
AesException
{
String
encrypt
=
encrypt
(
getRandomStr
(),
replyMsg
);
String
signature
=
SHA1
.
getSHA1
(
token
,
timeStamp
,
nonce
,
encrypt
);
return
XMLParse
.
generate
(
encrypt
,
signature
,
timeStamp
,
nonce
);
}
/**
* 检验消息的真实性,并且获取解密后的明文.
*/
public
String
DecryptMsg
(
String
msgSignature
,
String
timeStamp
,
String
nonce
,
String
postData
)
throws
AesException
{
Object
[]
encrypt
=
XMLParse
.
extract
(
postData
);
String
signature
=
SHA1
.
getSHA1
(
token
,
timeStamp
,
nonce
,
encrypt
[
1
].
toString
());
if
(!
signature
.
equals
(
msgSignature
))
{
throw
new
AesException
(
AesException
.
ValidateSignatureError
);
}
return
decrypt
(
encrypt
[
1
].
toString
());
}
/**
* 验证URL
*/
public
String
VerifyURL
(
String
msgSignature
,
String
timeStamp
,
String
nonce
,
String
echoStr
)
throws
AesException
{
String
signature
=
SHA1
.
getSHA1
(
token
,
timeStamp
,
nonce
,
echoStr
);
if
(!
signature
.
equals
(
msgSignature
))
{
throw
new
AesException
(
AesException
.
ValidateSignatureError
);
}
return
decrypt
(
echoStr
);
}
}
src/main/java/cn/com/poc/user/wecom/util/XMLParse.java
0 → 100644
View file @
5c402aa7
package
cn
.
com
.
poc
.
user
.
wecom
.
util
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.NodeList
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
java.io.ByteArrayInputStream
;
import
java.io.InputStream
;
import
java.nio.charset.StandardCharsets
;
/**
* XML解析器
*/
class
XMLParse
{
public
static
Object
[]
extract
(
String
xmltext
)
throws
AesException
{
try
{
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
dbf
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
InputStream
inputStream
=
new
ByteArrayInputStream
(
xmltext
.
getBytes
(
StandardCharsets
.
UTF_8
));
Document
doc
=
db
.
parse
(
inputStream
);
Element
root
=
doc
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
NodeList
nodelist2
=
root
.
getElementsByTagName
(
"ToUserName"
);
if
(
nodelist1
.
getLength
()
==
0
)
{
throw
new
AesException
(
AesException
.
ParseXmlError
);
}
String
encrypt
=
nodelist1
.
item
(
0
).
getTextContent
();
String
toUserName
=
nodelist2
.
item
(
0
).
getTextContent
();
return
new
Object
[]{
toUserName
,
encrypt
};
}
catch
(
Exception
e
)
{
throw
new
AesException
(
AesException
.
ParseXmlError
);
}
}
public
static
String
generate
(
String
encrypt
,
String
signature
,
String
timestamp
,
String
nonce
)
{
return
"<xml>\n"
+
"<Encrypt><![CDATA["
+
encrypt
+
"]]></Encrypt>\n"
+
"<MsgSignature><![CDATA["
+
signature
+
"]]></MsgSignature>\n"
+
"<TimeStamp>"
+
timestamp
+
"</TimeStamp>\n"
+
"<Nonce><![CDATA["
+
nonce
+
"]]></Nonce>\n"
+
"</xml>"
;
}
}
src/main/resources/framemax-config/config-dev.properties
View file @
5c402aa7
...
...
@@ -30,4 +30,12 @@ google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleuserco
google.custom.search.key
=
AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw
google.custom.search.cx
=
049026ecb26e840ed
wecom.corpid
=
ww8c108fef054eadf7
wecom.provider_secret
=
CFNGYoy2zByD_6Sn77JKO2spuuk6qwCNR64awuPiEbCby7sRnAnHN4XN8q8o5avB
wecom.suite_id
=
ww082e840d854324af
wecom.suite_secret
=
RkZgVTuIx6vZxpXWZDHmbIE1KZeSCPYuf9ImfLGeGIE
wecom.redirect_url
=
https://software-copyright-sit.gsstcloud.com/login
wecom.token
=
pemLJjdcbM
wecom.encoding_aes_key
=
eHLt8oIYfnp9E27zINRUhusKyQmvFrc64w3ccPho5HG
dify.software_copyright.callball.url
=
https://super-modellink-sit.gsstcloud.com/api/rest/bizSoftwareCopyrightRest/callbackGeneratedBaseDoc.json
\ No newline at end of file
src/main/resources/framemax-config/config.properties
View file @
5c402aa7
...
...
@@ -72,3 +72,11 @@ framemax-frame.job.disable=false
#pay
pay.config.acctId
=
16653311814572
pay.config.wxAppId
=
wxea3470b5d2d97eca
wecom.corpid
=
ww8c108fef054eadf7
wecom.provider_secret
=
CFNGYoy2zByD_6Sn77JKO2spuuk6qwCNR64awuPiEbCby7sRnAnHN4XN8q8o5avB
wecom.suite_id
=
ww082e840d854324af
wecom.suite_secret
=
RkZgVTuIx6vZxpXWZDHmbIE1KZeSCPYuf9ImfLGeGIE
wecom.redirect_url
=
https://software-copyright-sit.gsstcloud.com/login
wecom.token
=
pemLJjdcbM
wecom.encoding_aes_key
=
eHLt8oIYfnp9E27zINRUhusKyQmvFrc64w3ccPho5HG
\ No newline at end of file
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