Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
sc_media
Project
Project
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
Graph
比较
统计图
议题
0
议题
0
列表
看板
标记
Milestones
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
注册表
注册表
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
svn
sc_media
Commits
52378c51
提交
52378c51
authored
8月 15, 2019
作者:
renjiancai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
上级
de8f7915
隐藏空白字符变更
内嵌
并排
正在显示
16 个修改的文件
包含
1345 行增加
和
43 行删除
+1345
-43
pom.xml
com.zrqx.resource/pom.xml
+24
-1
.WXBizMsgCrypt.java.swp
...ain/java/com/zrqx/resource/bg/aes/.WXBizMsgCrypt.java.swp
+0
-0
AesException.java
.../src/main/java/com/zrqx/resource/bg/aes/AesException.java
+59
-0
ByteGroup.java
...rce/src/main/java/com/zrqx/resource/bg/aes/ByteGroup.java
+26
-0
PKCS7Encoder.java
.../src/main/java/com/zrqx/resource/bg/aes/PKCS7Encoder.java
+67
-0
SHA1.java
...resource/src/main/java/com/zrqx/resource/bg/aes/SHA1.java
+61
-0
WXBizMsgCrypt.java
...src/main/java/com/zrqx/resource/bg/aes/WXBizMsgCrypt.java
+288
-0
WXBizMsgCryptTest.java
...main/java/com/zrqx/resource/bg/aes/WXBizMsgCryptTest.java
+152
-0
XMLParse.java
...urce/src/main/java/com/zrqx/resource/bg/aes/XMLParse.java
+81
-0
WechatAuthorization.java
.../com/zrqx/resource/bg/controller/WechatAuthorization.java
+348
-0
WeChatConfig.java
.../com/zrqx/resource/bg/controller/config/WeChatConfig.java
+3
-2
WechatStaticData.java
.../zrqx/resource/bg/controller/config/WechatStaticData.java
+2
-2
ArticleLibraryController.java
...ource/bg/controller/content/ArticleLibraryController.java
+3
-4
UserController.java
.../com/zrqx/resource/bg/controller/user/UserController.java
+136
-19
Program.java
...urce/src/main/java/com/zrqx/resource/bg/util/Program.java
+65
-0
Redis.java
...source/src/main/java/com/zrqx/resource/commons/Redis.java
+30
-15
没有找到文件。
com.zrqx.resource/pom.xml
浏览文件 @
52378c51
...
...
@@ -17,6 +17,7 @@
<groupId>
com.zrqx
</groupId>
<artifactId>
com.zrqx.core
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-redis
</artifactId>
...
...
@@ -48,7 +49,11 @@
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-openfeign
</artifactId>
</dependency>
<dependency>
<groupId>
commons-codec
</groupId>
<artifactId>
commons-codec
</artifactId>
<version>
1.9
</version>
</dependency>
<!--熔断器 -->
<dependency>
<groupId>
org.springframework.cloud
</groupId>
...
...
@@ -101,12 +106,30 @@
<artifactId>
jsoup
</artifactId>
<version>
1.11.3
</version>
</dependency>
<dependency>
<groupId>
dom4j
</groupId>
<artifactId>
dom4j
</artifactId>
<version>
1.6.1
</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jeewx/jeewx-api -->
<dependency>
<groupId>
org.jeewx
</groupId>
<artifactId>
jeewx-api
</artifactId>
<version>
1.2.0
</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->
<dependency>
<groupId>
net.sf.json-lib
</groupId>
<artifactId>
json-lib-ext-spring
</artifactId>
<version>
1.0.2
</version>
</dependency>
<!--用于测试的 -->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
</dependency>
<!-- 热部署工具 -->
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId>
</dependency> -->
...
...
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/.WXBizMsgCrypt.java.swp
0 → 100644
浏览文件 @
52378c51
File added
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/AesException.java
0 → 100644
浏览文件 @
52378c51
package
com
.
zrqx
.
resource
.
bg
.
aes
;
@SuppressWarnings
(
"serial"
)
public
class
AesException
extends
Exception
{
public
final
static
int
OK
=
0
;
public
final
static
int
ValidateSignatureError
=
-
40001
;
public
final
static
int
ParseXmlError
=
-
40002
;
public
final
static
int
ComputeSignatureError
=
-
40003
;
public
final
static
int
IllegalAesKey
=
-
40004
;
public
final
static
int
ValidateAppidError
=
-
40005
;
public
final
static
int
EncryptAESError
=
-
40006
;
public
final
static
int
DecryptAESError
=
-
40007
;
public
final
static
int
IllegalBuffer
=
-
40008
;
//public final static int EncodeBase64Error = -40009;
//public final static int DecodeBase64Error = -40010;
//public final static int GenReturnXmlError = -40011;
private
int
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
ValidateAppidError:
return
"appid校验失败"
;
case
EncryptAESError:
return
"aes加密失败"
;
case
DecryptAESError:
return
"aes解密失败"
;
case
IllegalBuffer:
return
"解密后得到的buffer非法"
;
// case EncodeBase64Error:
// return "base64加密错误";
// case DecodeBase64Error:
// return "base64解密错误";
// case GenReturnXmlError:
// return "xml生成失败";
default
:
return
null
;
// cannot be
}
}
public
int
getCode
()
{
return
code
;
}
AesException
(
int
code
)
{
super
(
getMessage
(
code
));
this
.
code
=
code
;
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/ByteGroup.java
0 → 100644
浏览文件 @
52378c51
package
com
.
zrqx
.
resource
.
bg
.
aes
;
import
java.util.ArrayList
;
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
();
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/PKCS7Encoder.java
0 → 100644
浏览文件 @
52378c51
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package
com
.
zrqx
.
resource
.
bg
.
aes
;
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
);
String
tmp
=
new
String
();
for
(
int
index
=
0
;
index
<
amountToPad
;
index
++)
{
tmp
+=
padChr
;
}
return
tmp
.
getBytes
(
CHARSET
);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted 解密后的明文
* @return 删除补位字符后的明文
*/
static
byte
[]
decode
(
byte
[]
decrypted
)
{
int
pad
=
(
int
)
decrypted
[
decrypted
.
length
-
1
];
if
(
pad
<
1
||
pad
>
32
)
{
pad
=
0
;
}
return
Arrays
.
copyOfRange
(
decrypted
,
0
,
decrypted
.
length
-
pad
);
}
/**
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
*
* @param a 需要转化的数字
* @return 转化得到的字符
*/
static
char
chr
(
int
a
)
{
byte
target
=
(
byte
)
(
a
&
0xFF
);
return
(
char
)
target
;
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/SHA1.java
0 → 100644
浏览文件 @
52378c51
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package
com
.
zrqx
.
resource
.
bg
.
aes
;
import
java.security.MessageDigest
;
import
java.util.Arrays
;
/**
* SHA1 class
*
* 计算公众平台的消息签名接口.
*/
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
};
StringBuffer
sb
=
new
StringBuffer
();
// 字符串排序
Arrays
.
sort
(
array
);
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
sb
.
append
(
array
[
i
]);
}
String
str
=
sb
.
toString
();
// SHA1签名生成
MessageDigest
md
=
MessageDigest
.
getInstance
(
"SHA-1"
);
md
.
update
(
str
.
getBytes
());
byte
[]
digest
=
md
.
digest
();
StringBuffer
hexstr
=
new
StringBuffer
();
String
shaHex
=
""
;
for
(
int
i
=
0
;
i
<
digest
.
length
;
i
++)
{
shaHex
=
Integer
.
toHexString
(
digest
[
i
]
&
0xFF
);
if
(
shaHex
.
length
()
<
2
)
{
hexstr
.
append
(
0
);
}
hexstr
.
append
(
shaHex
);
}
return
hexstr
.
toString
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
AesException
(
AesException
.
ComputeSignatureError
);
}
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/WXBizMsgCrypt.java
0 → 100644
浏览文件 @
52378c51
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
/**
* 针对org.apache.commons.codec.binary.Base64,
* 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
* 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
*/
package
com
.
zrqx
.
resource
.
bg
.
aes
;
import
java.nio.charset.Charset
;
import
java.util.Arrays
;
import
java.util.Random
;
import
javax.crypto.Cipher
;
import
javax.crypto.spec.IvParameterSpec
;
import
javax.crypto.spec.SecretKeySpec
;
import
org.apache.commons.codec.binary.Base64
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串).
* <ol>
* <li>第三方回复加密消息给公众平台</li>
* <li>第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。</li>
* </ol>
* 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
* <ol>
* <li>在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:
* http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</li>
* <li>下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
* <li>如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
* <li>如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
* </ol>
*/
public
class
WXBizMsgCrypt
{
static
Charset
CHARSET
=
Charset
.
forName
(
"utf-8"
);
Base64
base64
=
new
Base64
();
byte
[]
aesKey
;
String
token
;
String
appId
;
private
final
static
Logger
log
=
LoggerFactory
.
getLogger
(
WXBizMsgCrypt
.
class
);
/**
* 构造函数
* @param token 公众平台上,开发者设置的token
* @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
* @param appId 公众平台appid
*
* @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
*/
public
WXBizMsgCrypt
(
String
token
,
String
encodingAesKey
,
String
appId
)
throws
AesException
{
if
(
encodingAesKey
.
length
()
!=
43
)
{
throw
new
AesException
(
AesException
.
IllegalAesKey
);
}
this
.
token
=
token
;
this
.
appId
=
appId
;
aesKey
=
Base64
.
decodeBase64
(
encodingAesKey
+
"="
);
}
// 生成4个字节的网络字节序
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
;
}
// 还原4个字节的网络字节序
int
recoverNetworkBytesOrder
(
byte
[]
orderBytes
)
{
int
sourceNumber
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
sourceNumber
<<=
8
;
sourceNumber
|=
orderBytes
[
i
]
&
0xff
;
}
return
sourceNumber
;
}
// 随机生成16位字符串
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
();
}
/**
* 对明文进行加密.
*
* @param text 需要加密的明文
* @return 加密后base64编码的字符串
* @throws AesException aes加密失败
*/
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
[]
appidBytes
=
appId
.
getBytes
(
CHARSET
);
// randomStr + networkBytesOrder + text + appid
byteCollector
.
addBytes
(
randomStrBytes
);
byteCollector
.
addBytes
(
networkBytesOrder
);
byteCollector
.
addBytes
(
textBytes
);
byteCollector
.
addBytes
(
appidBytes
);
// ... + pad: 使用自定义的填充方式对明文进行补位填充
byte
[]
padBytes
=
PKCS7Encoder
.
encode
(
byteCollector
.
size
());
byteCollector
.
addBytes
(
padBytes
);
// 获得最终的字节流, 未加密
byte
[]
unencrypted
=
byteCollector
.
toBytes
();
try
{
// 设置加密模式为AES的CBC模式
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
);
// 使用BASE64对加密后的字符串进行编码
String
base64Encrypted
=
base64
.
encodeToString
(
encrypted
);
return
base64Encrypted
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
AesException
(
AesException
.
EncryptAESError
);
}
}
/**
* 对密文进行解密.
*
* @param text 需要解密的密文
* @return 解密得到的明文
* @throws AesException aes解密失败
*/
String
decrypt
(
String
text
)
throws
AesException
{
byte
[]
original
;
try
{
// 设置解密模式为AES的CBC模式
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
);
// 使用BASE64对密文进行解码
byte
[]
encrypted
=
Base64
.
decodeBase64
(
text
);
// 解密
original
=
cipher
.
doFinal
(
encrypted
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
AesException
(
AesException
.
DecryptAESError
);
}
String
xmlContent
,
from_appid
;
try
{
// 去除补位字符
byte
[]
bytes
=
PKCS7Encoder
.
decode
(
original
);
// 分离16位随机字符串,网络字节序和AppId
byte
[]
networkOrder
=
Arrays
.
copyOfRange
(
bytes
,
16
,
20
);
int
xmlLength
=
recoverNetworkBytesOrder
(
networkOrder
);
xmlContent
=
new
String
(
Arrays
.
copyOfRange
(
bytes
,
20
,
20
+
xmlLength
),
CHARSET
);
from_appid
=
new
String
(
Arrays
.
copyOfRange
(
bytes
,
20
+
xmlLength
,
bytes
.
length
),
CHARSET
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
AesException
(
AesException
.
IllegalBuffer
);
}
// appid不相同的情况
if
(!
from_appid
.
equals
(
appId
))
{
throw
new
AesException
(
AesException
.
ValidateAppidError
);
}
return
xmlContent
;
}
/**
* 将公众平台回复用户的消息加密打包.
* <ol>
* <li>对要发送的消息进行AES-CBC加密</li>
* <li>生成安全签名</li>
* <li>将消息密文和安全签名打包成xml格式</li>
* </ol>
*
* @param replyMsg 公众平台待回复用户的消息,xml格式的字符串
* @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp
* @param nonce 随机串,可以自己生成,也可以用URL参数的nonce
*
* @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
* @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
*/
public
String
encryptMsg
(
String
replyMsg
,
String
timeStamp
,
String
nonce
)
throws
AesException
{
// 加密
String
encrypt
=
encrypt
(
getRandomStr
(),
replyMsg
);
// 生成安全签名
if
(
timeStamp
==
""
)
{
timeStamp
=
Long
.
toString
(
System
.
currentTimeMillis
());
}
String
signature
=
SHA1
.
getSHA1
(
token
,
timeStamp
,
nonce
,
encrypt
);
// System.out.println("发送给平台的签名是: " + signature[1].toString());
// 生成发送的xml
String
result
=
XMLParse
.
generate
(
encrypt
,
signature
,
timeStamp
,
nonce
);
return
result
;
}
/**
* 检验消息的真实性,并且获取解密后的明文.
* <ol>
* <li>利用收到的密文生成安全签名,进行签名验证</li>
* <li>若验证通过,则提取xml中的加密消息</li>
* <li>对消息进行解密</li>
* </ol>
*
* @param msgSignature 签名串,对应URL参数的msg_signature
* @param timeStamp 时间戳,对应URL参数的timestamp
* @param nonce 随机串,对应URL参数的nonce
* @param postData 密文,对应POST请求的数据
*
* @return 解密后的原文
* @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
*/
public
String
decryptMsg
(
String
msgSignature
,
String
timeStamp
,
String
nonce
,
String
postData
)
throws
AesException
{
// 密钥,公众账号的app secret
// 提取密文
Object
[]
encrypt
=
XMLParse
.
extract
(
postData
);
// 验证安全签名
String
signature
=
SHA1
.
getSHA1
(
token
,
timeStamp
,
nonce
,
encrypt
[
1
].
toString
());
// 和URL中的签名比较是否相等
// System.out.println("第三方收到URL中的签名:" + msg_sign);
// System.out.println("第三方校验签名:" + signature);
if
(!
signature
.
equals
(
msgSignature
))
{
throw
new
AesException
(
AesException
.
ValidateSignatureError
);
}
// 解密
String
result
=
decrypt
(
encrypt
[
1
].
toString
());
return
result
;
}
/**
* 验证URL
* @param msgSignature 签名串,对应URL参数的msg_signature
* @param timeStamp 时间戳,对应URL参数的timestamp
* @param nonce 随机串,对应URL参数的nonce
* @param echoStr 随机串,对应URL参数的echostr
*
* @return 解密之后的echostr
* @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
*/
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
);
}
String
result
=
decrypt
(
echoStr
);
return
result
;
}
}
\ No newline at end of file
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/WXBizMsgCryptTest.java
0 → 100644
浏览文件 @
52378c51
package
com
.
zrqx
.
resource
.
bg
.
aes
;
import
static
org
.
junit
.
Assert
.*;
import
java.io.IOException
;
import
java.io.StringReader
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
javax.xml.parsers.ParserConfigurationException
;
import
org.junit.After
;
import
org.junit.AfterClass
;
import
org.junit.Before
;
import
org.junit.BeforeClass
;
import
org.junit.Test
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
public
class
WXBizMsgCryptTest
{
String
encodingAesKey
=
"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG"
;
String
token
=
"pamtest"
;
String
timestamp
=
"1409304348"
;
String
nonce
=
"xxxxxx"
;
String
appId
=
"wxb11529c136998cb6"
;
String
replyMsg
=
"我是中文abcd123"
;
String
xmlFormat
=
"<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>"
;
String
afterAesEncrypt
=
"jn1L23DB+6ELqJ+6bruv21Y6MD7KeIfP82D6gU39rmkgczbWwt5+3bnyg5K55bgVtVzd832WzZGMhkP72vVOfg=="
;
String
randomStr
=
"aaaabbbbccccdddd"
;
String
replyMsg2
=
"<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>"
;
String
afterAesEncrypt2
=
"jn1L23DB+6ELqJ+6bruv23M2GmYfkv0xBh2h+XTBOKVKcgDFHle6gqcZ1cZrk3e1qjPQ1F4RsLWzQRG9udbKWesxlkupqcEcW7ZQweImX9+wLMa0GaUzpkycA8+IamDBxn5loLgZpnS7fVAbExOkK5DYHBmv5tptA9tklE/fTIILHR8HLXa5nQvFb3tYPKAlHF3rtTeayNf0QuM+UW/wM9enGIDIJHF7CLHiDNAYxr+r+OrJCmPQyTy8cVWlu9iSvOHPT/77bZqJucQHQ04sq7KZI27OcqpQNSto2OdHCoTccjggX5Z9Mma0nMJBU+jLKJ38YB1fBIz+vBzsYjrTmFQ44YfeEuZ+xRTQwr92vhA9OxchWVINGC50qE/6lmkwWTwGX9wtQpsJKhP+oS7rvTY8+VdzETdfakjkwQ5/Xka042OlUb1/slTwo4RscuQ+RdxSGvDahxAJ6+EAjLt9d8igHngxIbf6YyqqROxuxqIeIch3CssH/LqRs+iAcILvApYZckqmA7FNERspKA5f8GoJ9sv8xmGvZ9Yrf57cExWtnX8aCMMaBropU/1k+hKP5LVdzbWCG0hGwx/dQudYR/eXp3P0XxjlFiy+9DMlaFExWUZQDajPkdPrEeOwofJb"
;
@BeforeClass
public
static
void
setUpBeforeClass
()
throws
Exception
{
}
@AfterClass
public
static
void
tearDownAfterClass
()
throws
Exception
{
}
@Before
public
void
setUp
()
throws
Exception
{
}
@After
public
void
tearDown
()
throws
Exception
{
}
@Test
public
void
testNormal
()
throws
ParserConfigurationException
,
SAXException
,
IOException
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
String
afterEncrpt
=
pc
.
encryptMsg
(
replyMsg
,
timestamp
,
nonce
);
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
StringReader
sr
=
new
StringReader
(
afterEncrpt
);
InputSource
is
=
new
InputSource
(
sr
);
Document
document
=
db
.
parse
(
is
);
Element
root
=
document
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
NodeList
nodelist2
=
root
.
getElementsByTagName
(
"MsgSignature"
);
String
encrypt
=
nodelist1
.
item
(
0
).
getTextContent
();
String
msgSignature
=
nodelist2
.
item
(
0
).
getTextContent
();
String
fromXML
=
String
.
format
(
xmlFormat
,
encrypt
);
// 第三方收到公众号平台发送的消息
String
afterDecrpt
=
pc
.
decryptMsg
(
msgSignature
,
timestamp
,
nonce
,
fromXML
);
assertEquals
(
replyMsg
,
afterDecrpt
);
}
catch
(
AesException
e
)
{
fail
(
"正常流程,怎么就抛出异常了??????"
);
}
}
@Test
public
void
testAesEncrypt
()
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
assertEquals
(
afterAesEncrypt
,
pc
.
encrypt
(
randomStr
,
replyMsg
));
}
catch
(
AesException
e
)
{
e
.
printStackTrace
();
fail
(
"no异常"
);
}
}
@Test
public
void
testAesEncrypt2
()
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
assertEquals
(
afterAesEncrypt2
,
pc
.
encrypt
(
randomStr
,
replyMsg2
));
}
catch
(
AesException
e
)
{
e
.
printStackTrace
();
fail
(
"no异常"
);
}
}
@Test
public
void
testIllegalAesKey
()
{
try
{
new
WXBizMsgCrypt
(
token
,
"abcde"
,
appId
);
}
catch
(
AesException
e
)
{
assertEquals
(
AesException
.
IllegalAesKey
,
e
.
getCode
());
return
;
}
fail
(
"错误流程不抛出异常???"
);
}
@Test
public
void
testValidateSignatureError
()
throws
ParserConfigurationException
,
SAXException
,
IOException
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
String
afterEncrpt
=
pc
.
encryptMsg
(
replyMsg
,
timestamp
,
nonce
);
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
StringReader
sr
=
new
StringReader
(
afterEncrpt
);
InputSource
is
=
new
InputSource
(
sr
);
Document
document
=
db
.
parse
(
is
);
Element
root
=
document
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
String
encrypt
=
nodelist1
.
item
(
0
).
getTextContent
();
String
fromXML
=
String
.
format
(
xmlFormat
,
encrypt
);
pc
.
decryptMsg
(
"12345"
,
timestamp
,
nonce
,
fromXML
);
// 这里签名错误
}
catch
(
AesException
e
)
{
assertEquals
(
AesException
.
ValidateSignatureError
,
e
.
getCode
());
return
;
}
fail
(
"错误流程不抛出异常???"
);
}
@Test
public
void
testVerifyUrl
()
throws
AesException
{
WXBizMsgCrypt
wxcpt
=
new
WXBizMsgCrypt
(
"QDG6eK"
,
"jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C"
,
"wx5823bf96d3bd56c7"
);
String
verifyMsgSig
=
"5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3"
;
String
timeStamp
=
"1409659589"
;
String
nonce
=
"263014780"
;
String
echoStr
=
"P9nAzCzyDtyTWESHep1vC5X9xho/qYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp+4RPcs8TgAE7OaBO+FZXvnaqQ=="
;
wxcpt
.
verifyUrl
(
verifyMsgSig
,
timeStamp
,
nonce
,
echoStr
);
// 只要不抛出异常就好
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/aes/XMLParse.java
0 → 100644
浏览文件 @
52378c51
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package
com
.
zrqx
.
resource
.
bg
.
aes
;
import
java.io.StringReader
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.InputSource
;
/**
* XMLParse class
*
* 提供提取消息格式中的密文及生成回复消息格式的接口.
*/
class
XMLParse
{
private
final
static
Logger
log
=
LoggerFactory
.
getLogger
(
XMLParse
.
class
);
/**
* 提取出xml数据包中的加密消息
* @param xmltext 待提取的xml字符串
* @return 提取出的加密消息字符串
* @throws AesException
*/
public
static
Object
[]
extract
(
String
xmltext
)
throws
AesException
{
Object
[]
result
=
new
Object
[
3
];
try
{
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
dbf
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
dbf
.
setFeature
(
"http://xml.org/sax/features/external-general-entities"
,
false
);
dbf
.
setFeature
(
"http://xml.org/sax/features/external-parameter-entities"
,
false
);
dbf
.
setFeature
(
"http://apache.org/xml/features/nonvalidating/load-external-dtd"
,
false
);
dbf
.
setXIncludeAware
(
false
);
dbf
.
setExpandEntityReferences
(
false
);
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
StringReader
sr
=
new
StringReader
(
xmltext
);
InputSource
is
=
new
InputSource
(
sr
);
Document
document
=
db
.
parse
(
is
);
Element
root
=
document
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
NodeList
nodelist2
=
root
.
getElementsByTagName
(
"ToUserName"
);
result
[
0
]
=
0
;
result
[
1
]
=
nodelist1
.
item
(
0
).
getTextContent
();
if
(
nodelist2
.
item
(
0
)
!=
null
){
result
[
2
]
=
nodelist2
.
item
(
0
).
getTextContent
();
}
return
result
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
AesException
(
AesException
.
ParseXmlError
);
}
}
/**
* 生成xml消息
* @param encrypt 加密后的消息密文
* @param signature 安全签名
* @param timestamp 时间戳
* @param nonce 随机字符串
* @return 生成的xml字符串
*/
public
static
String
generate
(
String
encrypt
,
String
signature
,
String
timestamp
,
String
nonce
)
{
String
format
=
"<xml>\n"
+
"<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
+
"<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
+
"<TimeStamp>%3$s</TimeStamp>\n"
+
"<Nonce><![CDATA[%4$s]]></Nonce>\n"
+
"</xml>"
;
return
String
.
format
(
format
,
encrypt
,
signature
,
timestamp
,
nonce
);
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/controller/WechatAuthorization.java
0 → 100644
浏览文件 @
52378c51
package
com
.
zrqx
.
resource
.
bg
.
controller
;
import
io.swagger.annotations.ApiOperation
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.util.Calendar
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.prefs.BackingStoreException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.xml.parsers.ParserConfigurationException
;
import
org.apache.commons.lang.StringUtils
;
import
org.dom4j.Document
;
import
org.dom4j.DocumentException
;
import
org.dom4j.DocumentHelper
;
import
org.dom4j.Element
;
import
org.jeewx.api.third.JwThirdAPI
;
import
org.jeewx.api.third.model.ApiComponentToken
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.servlet.ModelAndView
;
import
org.xml.sax.SAXException
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zrqx.core.util.https.HttpClientUtil
;
import
com.zrqx.core.util.response.CallBack
;
import
com.zrqx.resource.bg.aes.AesException
;
import
com.zrqx.resource.bg.aes.WXBizMsgCrypt
;
import
com.zrqx.resource.bg.controller.config.WeChatConfig
;
import
com.zrqx.resource.commons.Redis
;
public
class
WechatAuthorization
{
private
final
static
Logger
log
=
LoggerFactory
.
getLogger
(
WechatAuthorization
.
class
);
@Autowired
private
Redis
redis
;
private
final
static
String
COMPONENT_APPID
=
WeChatConfig
.
WECHAT_ClIENT_Id
;
private
final
static
String
COMPONENT_APPSECRET
=
WeChatConfig
.
WECHAT_ClIENT_SECRET
;
private
final
static
String
COMPONENT_ENCODINGAESKEY
=
"RDXJ9DzpjPpjSfETvAy08PDUlvZlhIibJWGP3yLuU5t"
;
private
final
static
String
COMPONENT_TOKEN
=
"23_4NeNfPBg37JfaYDZE8yDWJJ-UldUUM5tPkRnhVp1LClx-ulojqNSdIdqni3083YVUlHfY8hg8s9N7jMYQM2iTSvqcG7ihwylq9RWmNH8-BkmRGvo7qrY6ZSlgen65rx7rMurguTblWXeBuNJYFDjABASZX"
;
/**
* 授权事件接收
* @param request
* @param response
* @return
* @throws IOException
* @throws AesException
* @throws SAXException
* @throws ParserConfigurationException
* @throws BackingStoreException
* @throws DocumentException
*/
@ApiOperation
(
value
=
"获取授权Code"
,
notes
=
"获取授权Code"
)
@PostMapping
(
value
=
"/vote/getCode"
)
public
CallBack
<
String
>
getCode
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
,
AesException
,
SAXException
,
ParserConfigurationException
,
BackingStoreException
,
DocumentException
{
processAuthorizeEvent
(
request
);
return
CallBack
.
success
();
}
/**
* 一键授权功能
* @return
*/
@ApiOperation
(
value
=
"公众号授权引导入口"
,
notes
=
"公众号授权引导入口"
)
@GetMapping
(
"/auth_open"
)
public
CallBack
<
String
>
getCode_Url
()
{
return
CallBack
.
success
(
redis
.
get
(
"Code_Url"
));
}
@RequestMapping
(
value
=
"/{appid}/callback"
)
public
void
acceptMessageAndEvent
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
,
AesException
,
DocumentException
{
String
appId
=
"wxd53422d70d076d82"
;
String
msgSignature
=
request
.
getParameter
(
"msg_signature"
);
log
.
info
(
"第三方平台全网发布-------------{appid}/callback-----------验证开始。。。。msg_signature="
+
msgSignature
);
if
(!
StringUtils
.
isNotBlank
(
msgSignature
))
return
;
// 微信推送给第三方开放平台的消息一定是加过密的,无消息加密无法解密消息
StringBuilder
sb
=
new
StringBuilder
();
BufferedReader
in
=
request
.
getReader
();
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
sb
.
append
(
line
);
}
in
.
close
();
String
xml
=
sb
.
toString
();
Document
doc
=
DocumentHelper
.
parseText
(
xml
);
Element
rootElt
=
doc
.
getRootElement
();
String
toUserName
=
rootElt
.
elementText
(
"ToUserName"
);
log
.
info
(
"全网发布接入检测消息反馈开始1111---------------APPID="
+
appId
+
"------------------------toUserName="
+
toUserName
);
//微信全网测试账号
if
(
StringUtils
.
equalsIgnoreCase
(
toUserName
,
appId
))
{
log
.
info
(
"全网发布接入检测消息反馈开始2222---------------APPID="
+
appId
+
"------------------------toUserName="
+
toUserName
);
checkWeixinAllNetworkCheck
(
request
,
response
,
xml
);
}
}
/**
* 处理授权事件的推送
*
* @param request
* @throws IOException
* @throws AesException
* @throws BackingStoreException
* @throws DocumentException
*/
public
void
processAuthorizeEvent
(
HttpServletRequest
request
)
throws
IOException
,
AesException
,
BackingStoreException
,
DocumentException
{
String
encodingAesKey
=
"RDXJ9DzpjPpjSfETvAy08PDUlvZlhIibJWGP3yLuU5t"
;
String
token
=
"23_4NeNfPBg37JfaYDZE8yDWJJ-UldUUM5tPkRnhVp1LClx-ulojqNSdIdqni3083YVUlHfY8hg8s9N7jMYQM2iTSvqcG7ihwylq9RWmNH8-BkmRGvo7qrY6ZSlgen65rx7rMurguTblWXeBuNJYFDjABASZX"
;
String
appId
=
"wxd53422d70d076d82"
;
String
nonce
=
request
.
getParameter
(
"nonce"
);
String
timestamp
=
request
.
getParameter
(
"timestamp"
);
String
msgSignature
=
request
.
getParameter
(
"msg_signature"
);
StringBuilder
sb
=
new
StringBuilder
();
BufferedReader
in
=
request
.
getReader
();
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
sb
.
append
(
line
);
}
String
xml
=
sb
.
toString
();
if
(
StringUtils
.
isEmpty
(
xml
)){
throw
new
BackingStoreException
(
"第三方平台全网发布-----------------------原始 Xml为空!"
);
}
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
String
xml1
=
pc
.
decryptMsg
(
msgSignature
,
timestamp
,
nonce
,
xml
);
log
.
error
(
"第三方平台全网发布1112222-----------------------解密后 Xml="
+
xml1
);
processAuthorizationEvent
(
xml1
);
}
/**
* 保存Ticket
*
* @param xml
* @throws DocumentException
* @throws IOException
*/
public
void
processAuthorizationEvent
(
String
xml
)
throws
DocumentException
,
IOException
{
Document
doc
;
doc
=
DocumentHelper
.
parseText
(
xml
);
Element
rootElt
=
doc
.
getRootElement
();
String
ticket
=
rootElt
.
elementText
(
"ComponentVerifyTicket"
);
//微信公众号
String
WeChat_client_id
=
"wxd53422d70d076d82"
;
String
WeChat_client_secret
=
"5c1cccaaf3daeb84303771693bee4ec3"
;
String
param
=
"{\"component_appid\":\""
+
WeChat_client_id
+
"\" ,\"component_appsecret\": \""
+
WeChat_client_secret
+
"\",\"component_verify_ticket\": \""
+
ticket
+
"\"}"
;
String
url_token
=
"https://api.weixin.qq.com/cgi-bin/component/api_component_token"
;
JSONObject
json
=
JSONArray
.
parseObject
(
param
);
String
result_token
=
HttpClientUtil
.
doPostW
(
url_token
,
"utf-8"
,
json
);
//{"component_access_token":"61W3mEpU66027wgNZ_MhGHNQDHnFATkDa9-2llqrMBjUwxRSNPbVsMmyD-yq8wZETSoE5NQgecigDrSHkPtIYA", "expires_in":7200}
JSONObject
jsonobj_WX
=
JSON
.
parseObject
(
result_token
);
log
.
info
(
"解密后的result_token++++++++++++++++++++++"
+
result_token
);
String
component_access_token
=
jsonobj_WX
.
getString
(
"component_access_token"
);
String
paramCode
=
"{\"component_appid\":\""
+
WeChat_client_id
+
"\"}"
;
String
url_code
=
"https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token="
+
component_access_token
;
JSONObject
jsonCode
=
JSONArray
.
parseObject
(
paramCode
);
String
result_Code
=
HttpClientUtil
.
doPostW
(
url_code
,
"utf-8"
,
jsonCode
);
JSONObject
jsonobj_Code
=
JSON
.
parseObject
(
result_Code
);
String
code
=
jsonobj_Code
.
getString
(
"pre_auth_code"
);
log
.
info
(
"解密后的Code++++++++++++++++++++++"
+
code
);
log
.
info
(
"第三方平台全网发布-----------------------解密后 ComponentVerifyTicket="
+
ticket
);
redis
.
delete
(
ticket
);
redis
.
set
(
"ticket"
,
ticket
);
getCode12
(
code
);
}
public
void
getCode12
(
String
ticket_value
)
throws
IOException
{
ModelAndView
mav1
=
new
ModelAndView
();
mav1
.
addObject
(
"url"
,
"https://mp.weixin.qq.com/cgi-bin/componentloginpage?"
+
"component_appid=wxd53422d70d076d82&"
+
"pre_auth_code="
+
ticket_value
+
"&"
+
"redirect_uri=http://test16.zhongdianyun.com/index.html&type=3"
);
mav1
.
setViewName
(
"open_auth"
);
mav1
.
addObject
(
"code"
,
"success"
);
String
model
=
mav1
.
getModel
().
toString
();
String
[]
str
=
model
.
split
(
","
);
String
code_Url
=
null
;
for
(
String
s
:
str
)
{
int
index
=
s
.
indexOf
(
"="
);
code_Url
=
s
.
substring
(
index
+
1
);
break
;
}
log
.
info
(
"Code_Url111111111122222222222222222++++++++++++++++++++++="
+
code_Url
);
redis
.
delete
(
code_Url
);
redis
.
set
(
"Code_Url"
,
code_Url
);
}
/**
* 获取授权账号信息
* @param appid
* @return
*/
/*public WeixinOpenAccountEntity getWeixinOpenAccount(String appid){
WeixinOpenAccountEntity entity = null;
List<WeixinOpenAccountEntity> ls = systemService.findByProperty(WeixinOpenAccountEntity.class, "appid", appid);
if(ls!=null && ls.size()!=0){
entity = ls.get(0);
}
return entity;
}*/
/**
* 获取授权的Appid
* @param xml
* @return
*/
public
String
getAuthorizerAppidFromXml
(
String
xml
)
{
Document
doc
;
try
{
doc
=
DocumentHelper
.
parseText
(
xml
);
Element
rootElt
=
doc
.
getRootElement
();
String
toUserName
=
rootElt
.
elementText
(
"ToUserName"
);
return
toUserName
;
}
catch
(
DocumentException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
return
null
;
}
public
void
checkWeixinAllNetworkCheck
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
xml
)
throws
DocumentException
,
IOException
,
AesException
{
String
nonce
=
request
.
getParameter
(
"nonce"
);
String
timestamp
=
request
.
getParameter
(
"timestamp"
);
String
msgSignature
=
request
.
getParameter
(
"msg_signature"
);
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
COMPONENT_TOKEN
,
COMPONENT_ENCODINGAESKEY
,
COMPONENT_APPID
);
xml
=
pc
.
decryptMsg
(
msgSignature
,
timestamp
,
nonce
,
xml
);
Document
doc
=
DocumentHelper
.
parseText
(
xml
);
Element
rootElt
=
doc
.
getRootElement
();
String
msgType
=
rootElt
.
elementText
(
"MsgType"
);
String
toUserName
=
rootElt
.
elementText
(
"ToUserName"
);
String
fromUserName
=
rootElt
.
elementText
(
"FromUserName"
);
log
.
info
(
"---全网发布接入检测--step.1-----------msgType="
+
msgType
+
"-----------------toUserName="
+
toUserName
+
"-----------------fromUserName="
+
fromUserName
);
log
.
info
(
"---全网发布接入检测--step.2-----------xml="
+
xml
);
if
(
"event"
.
equals
(
msgType
)){
log
.
info
(
"---全网发布接入检测--step.3-----------事件消息--------"
);
String
event
=
rootElt
.
elementText
(
"Event"
);
replyEventMessage
(
request
,
response
,
event
,
toUserName
,
fromUserName
);
}
else
if
(
"text"
.
equals
(
msgType
)){
log
.
info
(
"---全网发布接入检测--step.3-----------文本消息--------"
);
String
content
=
rootElt
.
elementText
(
"Content"
);
processTextMessage
(
request
,
response
,
content
,
toUserName
,
fromUserName
);
}
}
public
void
replyEventMessage
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
event
,
String
toUserName
,
String
fromUserName
)
throws
DocumentException
,
IOException
{
String
content
=
event
+
"from_callback"
;
log
.
info
(
"---全网发布接入检测------step.4-------事件回复消息 content="
+
content
+
" toUserName="
+
toUserName
+
" fromUserName="
+
fromUserName
);
replyTextMessage
(
request
,
response
,
content
,
toUserName
,
fromUserName
);
}
public
void
processTextMessage
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
content
,
String
toUserName
,
String
fromUserName
)
throws
IOException
,
DocumentException
{
if
(
"TESTCOMPONENT_MSG_TYPE_TEXT"
.
equals
(
content
)){
String
returnContent
=
content
+
"_callback"
;
replyTextMessage
(
request
,
response
,
returnContent
,
toUserName
,
fromUserName
);
}
else
if
(
StringUtils
.
startsWithIgnoreCase
(
content
,
"QUERY_AUTH_CODE"
)){
//output(response, "");
//接下来客服API再回复一次消息
replyApiTextMessage
(
request
,
response
,
content
.
split
(
":"
)[
1
],
fromUserName
);
}
}
public
void
replyApiTextMessage
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
auth_code
,
String
fromUserName
)
throws
DocumentException
,
IOException
{
String
authorization_code
=
auth_code
;
// 得到微信授权成功的消息后,应该立刻进行处理!!相关信息只会在首次授权的时候推送过来
System
.
out
.
println
(
"------step.1----使用客服消息接口回复粉丝----逻辑开始-------------------------"
);
try
{
ApiComponentToken
apiComponentToken
=
new
ApiComponentToken
();
apiComponentToken
.
setComponent_appid
(
COMPONENT_APPID
);
apiComponentToken
.
setComponent_appsecret
(
COMPONENT_APPSECRET
);
//WeixinOpenAccountEntity entity = getWeixinOpenAccount(APPID);
apiComponentToken
.
setComponent_verify_ticket
(
redis
.
get
(
"ticket"
));
String
component_access_token
=
JwThirdAPI
.
getAccessToken
(
apiComponentToken
);
System
.
out
.
println
(
"------step.2----使用客服消息接口回复粉丝------- component_access_token = "
+
component_access_token
+
"---------authorization_code = "
+
authorization_code
);
net
.
sf
.
json
.
JSONObject
authorizationInfoJson
=
JwThirdAPI
.
getApiQueryAuthInfo
(
COMPONENT_APPID
,
authorization_code
,
component_access_token
);
System
.
out
.
println
(
"------step.3----使用客服消息接口回复粉丝-------------- 获取authorizationInfoJson = "
+
authorizationInfoJson
);
net
.
sf
.
json
.
JSONObject
infoJson
=
authorizationInfoJson
.
getJSONObject
(
"authorization_info"
);
String
authorizer_access_token
=
infoJson
.
getString
(
"authorizer_access_token"
);
Map
<
String
,
Object
>
obj
=
new
HashMap
<
String
,
Object
>();
Map
<
String
,
Object
>
msgMap
=
new
HashMap
<
String
,
Object
>();
String
msg
=
auth_code
+
"_from_api"
;
msgMap
.
put
(
"content"
,
msg
);
obj
.
put
(
"touser"
,
fromUserName
);
obj
.
put
(
"msgtype"
,
"text"
);
obj
.
put
(
"text"
,
msgMap
);
JwThirdAPI
.
sendMessage
(
obj
,
authorizer_access_token
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
/**
* 回复微信服务器"文本消息"
* @param request
* @param response
* @param content
* @param toUserName
* @param fromUserName
* @throws DocumentException
* @throws IOException
*/
public
void
replyTextMessage
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
content
,
String
toUserName
,
String
fromUserName
)
throws
DocumentException
,
IOException
{
Long
createTime
=
Calendar
.
getInstance
().
getTimeInMillis
()
/
1000
;
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
"<xml>"
);
sb
.
append
(
"<ToUserName><![CDATA["
+
fromUserName
+
"]]></ToUserName>"
);
sb
.
append
(
"<FromUserName><![CDATA["
+
toUserName
+
"]]></FromUserName>"
);
sb
.
append
(
"<CreateTime>"
+
createTime
+
"</CreateTime>"
);
sb
.
append
(
"<MsgType><![CDATA[text]]></MsgType>"
);
sb
.
append
(
"<Content><![CDATA["
+
content
+
"]]></Content>"
);
sb
.
append
(
"</xml>"
);
String
replyMsg
=
sb
.
toString
();
String
returnvaleue
=
""
;
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
COMPONENT_TOKEN
,
COMPONENT_ENCODINGAESKEY
,
COMPONENT_APPID
);
returnvaleue
=
pc
.
encryptMsg
(
replyMsg
,
createTime
.
toString
(),
"easemob"
);
// System.out.println("------------------加密后的返回内容 returnvaleue: "+returnvaleue);
}
catch
(
AesException
e
)
{
e
.
printStackTrace
();
}
output
(
response
,
returnvaleue
);
}
/**
* 工具类:回复微信服务器"文本消息"
* @param response
* @param returnvaleue
*/
public
void
output
(
HttpServletResponse
response
,
String
returnvaleue
){
try
{
PrintWriter
pw
=
response
.
getWriter
();
pw
.
write
(
returnvaleue
);
pw
.
flush
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/controller/config/WeChatConfig.java
浏览文件 @
52378c51
...
...
@@ -9,9 +9,10 @@ public class WeChatConfig {
/**
* 微信公众号appid
*/
public
final
static
String
WECHAT_ClIENT_Id
=
"wx
a036be65443d937f
"
;
public
final
static
String
WECHAT_ClIENT_Id
=
"wx
d53422d70d076d82
"
;
/**
* 微信公众号AppSecret
*/
public
final
static
String
WECHAT_ClIENT_SECRET
=
"e2070c6ac1a3c465042320d17a946479"
;
public
final
static
String
WECHAT_ClIENT_SECRET
=
"5c1cccaaf3daeb84303771693bee4ec3"
;
}
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/controller/config/WechatStaticData.java
浏览文件 @
52378c51
...
...
@@ -48,11 +48,11 @@ public class WechatStaticData {
/**
* 获取用户access_token
*/
public
final
static
String
OAUTT2_PATH
=
"https://api.weixin.qq.com/
sns/oauth2/access_token?appid
="
;
public
final
static
String
OAUTT2_PATH
=
"https://api.weixin.qq.com/
cgi-bin/component/api_query_auth?component_access_token
="
;
/**
* 获取用户信息
*/
public
final
static
String
USERINFO_PATH
=
"https://api.weixin.qq.com/
sns/userinfo?
access_token="
;
public
final
static
String
USERINFO_PATH
=
"https://api.weixin.qq.com/
cgi-bin/component/api_get_authorizer_info?component_
access_token="
;
/**
* 图片上传微信url
*/
...
...
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/controller/content/ArticleLibraryController.java
浏览文件 @
52378c51
...
...
@@ -404,7 +404,7 @@ public class ArticleLibraryController {
List
<
ArticleRelation
>
list
=
articleRelationService
.
selectByCriteria
();
if
(
list
.
size
()>
0
){
for
(
ArticleRelation
resourceRelation
:
list
)
{
userAccountRelationService
.
createCriteria
().
andEqualTo
(
"
original_author"
,
resourceRelation
.
getOriginal_author
());
userAccountRelationService
.
createCriteria
().
andEqualTo
(
"
account"
,
resourceRelation
.
getAccount
());
UserAccountRelation
user
=
userAccountRelationService
.
selectOneByCriteria
();
//企鹅号
if
(
form
.
getOriginal_author
().
get
(
i
).
equals
(
"1"
)){
...
...
@@ -422,10 +422,10 @@ public class ArticleLibraryController {
JSONObject
jsonobj_url
=
JSON
.
parseObject
(
excute
);
//成功结果:{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
String
thumb_media_id
=
jsonobj_url
.
getString
(
"media_id"
);
//String thumb_media_id ="
_4vt4k61UkTmNZdz2-HVHBQtPNHVvUbbEbrpQT6L7RhxxoGyiuogGlOC4EopHdCQ
";
//String thumb_media_id ="
bBnUF9ZEV1P09gmeGGoaOrFYTIdchZWEc4ZJ32ZPhgyUB5hOrh30hHvca15hreeR
";
String
content
=
library
.
getText
().
replaceAll
(
" "
,
""
);
String
param
=
"{\"articles\":[{\"thumb_media_id\":\""
+
thumb_media_id
+
"\",\"author\":\""
+
user
.
getAccountName
()+
"\",\"title\":\""
+
library
.
getTitle
()+
"\",\"content\":\""
+
content
+
"\",\"show_cover_pic\":1,\"need_open_comment\":1,\"only_fans_can_comment\":1}]}"
;
String
url_Wx
=
WechatStaticData
.
UPLOAD_SENDALL_NEWS
;
String
url_Wx
=
WechatStaticData
.
UPLOAD_SENDALL_NEWS
+
user
.
getAccess_token
()
;
JSONObject
json
=
JSONArray
.
parseObject
(
param
);
String
result_Wx
=
HttpClientUtil
.
doPostW
(
url_Wx
,
"utf-8"
,
json
);
JSONObject
jsonobj_WX
=
JSON
.
parseObject
(
result_Wx
);
...
...
@@ -436,7 +436,6 @@ public class ArticleLibraryController {
if
(
news
.
equals
(
"news"
)){
//根据标签进行群发,图文消息
param1
=
"{\"filter\":{\"is_to_all\":true,\"tag_id\":null},\"mpnews\":{\"media_id\":\""
+
media_id
+
"\"},\"msgtype\":\"mpnews\",\"send_ignore_reprint\":0}"
;
//param1="{\"touser\":\"o2MPM5jh1V8p_X0nC5D5ejsWPOLs\",\"mpnews\":{\"media_id\":\""+media_id+"\"},\"msgtype\":\"mpnews\"}";
}
else
if
(
news
.
equals
(
"image"
)){
//获取图片
param1
=
"{\"filter\":{\"is_to_all\":true,\"tag_id\":},\"image\":{\"media_id\":\""
+
media_id
+
"\"},\"msgtype\":\"image\"}"
;
...
...
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/controller/user/UserController.java
浏览文件 @
52378c51
...
...
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiOperation;
import
java.awt.image.BufferedImage
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.HashMap
;
...
...
@@ -14,10 +15,12 @@ import java.util.concurrent.TimeUnit;
import
javax.imageio.ImageIO
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpSession
;
import
org.apache.commons.lang.StringUtils
;
import
org.dom4j.DocumentException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
...
...
@@ -28,11 +31,12 @@ import org.springframework.web.bind.annotation.RequestBody;
import
org.springframework.web.bind.annotation.RequestHeader
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.servlet.ModelAndView
;
import
sun.misc.BASE64Encoder
;
import
tk.mybatis.mapper.entity.Example.Criteria
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zrqx.core.constant.member.MemberRequestPath
;
import
com.zrqx.core.constant.resource.ResourceRequestPath
;
...
...
@@ -68,6 +72,7 @@ import com.zrqx.resource.commons.Redis;
@RequestMapping
(
SysUserRequestPath
.
BG
+
SysUserRequestPath
.
USER
)
@Api
(
description
=
"权限管理-用户"
)
public
class
UserController
{
private
final
static
Logger
log
=
LoggerFactory
.
getLogger
(
UserController
.
class
);
@Autowired
StringRedisTemplate
stringRedisTemplate
;
@Autowired
...
...
@@ -195,15 +200,120 @@ public class UserController {
}
@ApiOperation
(
value
=
"获取授权Code"
,
notes
=
"获取授权Code"
)
@PostMapping
(
value
=
"/vote/getCode"
)
public
CallBack
<
String
>
getCode
(){
public
CallBack
<
String
>
getCode
(
String
ticket_value
){
//微信公众号
String
WeChat_client_id
=
WeChatConfig
.
WECHAT_ClIENT_Id
;
String
Url
=
"https://open.weixin.qq.com/connect/oauth2/authorize?appid="
+
WeChat_client_id
+
"&redirect_uri=http://test16.zhongdianyun.com/bg/user/vote/getCode&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect"
;
String
[]
Urlarr
=
Url
.
split
(
"?"
);
String
code
=
Urlarr
[
1
].
split
(
"="
)[
1
].
split
(
"&"
)[
0
];
String
WeChat_client_secret
=
WeChatConfig
.
WECHAT_ClIENT_SECRET
;
String
param
=
"{\"component_appid\":\""
+
WeChat_client_id
+
"\" ,\"component_appsecret\": \""
+
WeChat_client_secret
+
"\",\"component_verify_ticket\": \""
+
ticket_value
+
"\"}"
;
String
url_token
=
"https://api.weixin.qq.com/cgi-bin/component/api_component_token"
;
JSONObject
json
=
JSONArray
.
parseObject
(
param
);
String
result_token
=
HttpClientUtil
.
doPostW
(
url_token
,
"utf-8"
,
json
);
//{"component_access_token":"61W3mEpU66027wgNZ_MhGHNQDHnFATkDa9-2llqrMBjUwxRSNPbVsMmyD-yq8wZETSoE5NQgecigDrSHkPtIYA", "expires_in":7200}
JSONObject
jsonobj_WX
=
JSON
.
parseObject
(
result_token
);
String
component_access_token
=
jsonobj_WX
.
getString
(
"component_access_token"
);
String
paramCode
=
"{\"component_appid\":\""
+
WeChat_client_id
+
"\"}"
;
String
url_code
=
"https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token="
+
component_access_token
;
JSONObject
jsonCode
=
JSONArray
.
parseObject
(
paramCode
);
String
result_Code
=
HttpClientUtil
.
doPostW
(
url_code
,
"utf-8"
,
jsonCode
);
JSONObject
jsonobj_Code
=
JSON
.
parseObject
(
result_Code
);
//{"pre_auth_code":"Cx_Dk6qiBE0Dmx4EmlT3oRfArPvwSQ-oa3NL_fwHM7VI08r52wazoZX2Rhpz1dEw","expires_in":600}
String
code
=
jsonobj_Code
.
getString
(
"pre_auth_code"
);
return
CallBack
.
success
(
code
);
}
//======================================测试微信登录需要===================================
/*@ApiOperation(value = "获取授权Code", notes = "获取授权Code")
@PostMapping(value= "/vote/getCode")
public CallBack<String> getCode(HttpServletRequest request, HttpServletResponse response) throws IOException, AesException, SAXException, ParserConfigurationException, BackingStoreException, DocumentException{
processAuthorizeEvent(request);
return CallBack.success();
}
*//**
* 处理授权事件的推送
*
* @param request
* @throws IOException
* @throws AesException
* @throws BackingStoreException
* @throws DocumentException
*//*
public void processAuthorizeEvent(HttpServletRequest request) throws IOException, AesException, BackingStoreException, DocumentException {
String encodingAesKey = "RDXJ9DzpjPpjSfETvAy08PDUlvZlhIibJWGP3yLuU5t";
String token = "23_4NeNfPBg37JfaYDZE8yDWJJ-UldUUM5tPkRnhVp1LClx-ulojqNSdIdqni3083YVUlHfY8hg8s9N7jMYQM2iTSvqcG7ihwylq9RWmNH8-BkmRGvo7qrY6ZSlgen65rx7rMurguTblWXeBuNJYFDjABASZX";
String appId="wxcb2f6d1e3f2f187d";
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
String msgSignature = request.getParameter("msg_signature");
StringBuilder sb = new StringBuilder();
BufferedReader in = request.getReader();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
String xml = sb.toString();
if(StringUtils.isEmpty(xml)){
throw new BaseException("第三方平台全网发布-----------------------原始 Xml为空!");
}
WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
String xml1 = pc.decryptMsg(msgSignature, timestamp, nonce, xml);
log.error("第三方平台全网发布111-----------------------解密后 Xml=" + xml1);
processAuthorizationEvent(xml1);
}
*//**
* 保存Ticket
*
* @param xml
* @throws DocumentException
* @throws IOException
*//*
public void processAuthorizationEvent(String xml) throws DocumentException, IOException {
Document doc;
doc = DocumentHelper.parseText(xml);
Element rootElt = doc.getRootElement();
String ticket = rootElt.elementText("ComponentVerifyTicket");
//微信公众号
String WeChat_client_id="wxcb2f6d1e3f2f187d";
String WeChat_client_secret="a6d70f9e0277b86fac2bd02cf29a2650";
String param="{\"component_appid\":\""+WeChat_client_id+"\" ,\"component_appsecret\": \""+WeChat_client_secret+"\",\"component_verify_ticket\": \""+ticket+"\"}";
String url_token="https://api.weixin.qq.com/cgi-bin/component/api_component_token";
JSONObject json=JSONArray.parseObject(param);
String result_token = HttpClientUtil.doPostW(url_token, "utf-8",json);
//{"component_access_token":"61W3mEpU66027wgNZ_MhGHNQDHnFATkDa9-2llqrMBjUwxRSNPbVsMmyD-yq8wZETSoE5NQgecigDrSHkPtIYA", "expires_in":7200}
JSONObject jsonobj_WX = JSON.parseObject(result_token);
log.info("解密后的result_token++++++++++++++++++++++"+result_token);
String component_access_token=jsonobj_WX.getString("component_access_token");
String paramCode="{\"component_appid\":\""+WeChat_client_id+"\"}";
String url_code="https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token="+component_access_token;
JSONObject jsonCode=JSONArray.parseObject(paramCode);
String result_Code = HttpClientUtil.doPostW(url_code, "utf-8",jsonCode);
JSONObject jsonobj_Code = JSON.parseObject(result_Code);
//{"pre_auth_code":"Cx_Dk6qiBE0Dmx4EmlT3oRfArPvwSQ-oa3NL_fwHM7VI08r52wazoZX2Rhpz1dEw","expires_in":600}
String code=jsonobj_Code.getString("pre_auth_code");
log.info("解密后的Code++++++++++++++++++++++"+code);
log.info("第三方平台全网发布-----------------------解密后 ComponentVerifyTicket=" + ticket);
}*/
@ApiOperation
(
value
=
"公众号授权引导入口"
,
notes
=
"公众号授权引导入口"
)
@GetMapping
(
"/auth_open"
)
public
CallBack
<
ModelAndView
>
indexOpen
(){
ModelAndView
mav
=
new
ModelAndView
();
mav
.
addObject
(
"url"
,
"https://mp.weixin.qq.com/cgi-bin/componentloginpage?"
+
"component_appid=wxcb2f6d1e3f2f187d&"
+
"pre_auth_code=@@@mrkgA79l7ZBwgwpUsT6lusBrqqXVihv9LPR21FYnRTkbShB9fDFdLB5Y3pAuKs22&"
+
"redirect_uri=http://test16.zhongdianyun.com/index.html&type=3"
);
mav
.
setViewName
(
"open_auth"
);
mav
.
addObject
(
"code"
,
"success"
);
String
model
=
mav
.
getModel
().
toString
();
String
[]
str
=
model
.
split
(
","
);
for
(
String
s
:
str
)
{
int
index
=
s
.
indexOf
(
"="
);
String
newStr
=
s
.
substring
(
index
+
1
);
System
.
out
.
println
(
"+++++++++++++url"
+
newStr
);
break
;
}
log
.
info
(
"解密后的model++++++++++++++++++++++"
+
model
);
return
CallBack
.
success
(
mav
);
}
@ApiOperation
(
value
=
"添加用户关联账号"
,
notes
=
"添加用户关联账号"
)
@PostMapping
(
value
=
ResourceRequestPath
.
SAVE
)
public
CallBack
<
Boolean
>
save
(
@RequestBody
SaveUserForm
form
){
...
...
@@ -212,7 +322,6 @@ public class UserController {
String
tencent_client_secret
=
TencentConfig
.
TENCENT_ClIENT_SECRET
;
//微信公众号
String
WeChat_client_id
=
WeChatConfig
.
WECHAT_ClIENT_Id
;
String
WeChat_client_secret
=
WeChatConfig
.
WECHAT_ClIENT_SECRET
;
//网易号
String
NetEase_client_id
=
NetEaseConfig
.
NETEASE_ClIENT_Id
;
String
NetEase_client_secret
=
NetEaseConfig
.
NETEASE_ClIENT_SECRET
;
...
...
@@ -247,16 +356,24 @@ public class UserController {
* http://test16.zhongdianyun.com:8196/bg/user/save&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect
*/
if
(
form
.
getOriginal_author
().
equals
(
2
)){
String
url_token
=
WechatStaticData
.
OAUTT2_PATH
+
WeChat_client_id
+
"&secret="
+
WeChat_client_secret
+
"&code="
+
form
.
getCode
()+
"&grant_type=authorization_code"
;
access_token
=
HttpClientUtil
.
doPost
(
url_token
,
"utf-8"
,
null
);
JSONObject
jsonobj_token
=
JSON
.
parseObject
(
access_token
);
token
=
jsonobj_token
.
getString
(
"access_token"
);
String
user
=
WechatStaticData
.
USERINFO_PATH
+
token
+
"&openid="
+
userId
+
"&lang=zh_CN"
;
String
tname
=
HttpClientUtil
.
doGet
(
user
,
"utf-8"
);
//获取账号名称
JSONObject
jsonobj_token1
=
JSON
.
parseObject
(
tname
);
userName
=
jsonobj_token1
.
getString
(
"nickname"
);
userId
=
jsonobj_token1
.
getString
(
"openid"
);
//引导进入授权页面(前台调用)
//使用授权码换取公众号或小程序的接口调用凭据和授权信息
String
paramUser
=
"{\"component_appid\":\""
+
WeChat_client_id
+
"\",\"authorization_code\": \""
+
form
.
getCode
()+
"\"}"
;
String
url_user
=
WechatStaticData
.
OAUTT2_PATH
+
form
.
getComponent_access_token
();
JSONObject
jsonUser
=
JSONArray
.
parseObject
(
paramUser
);
String
result_User
=
HttpClientUtil
.
doPostW
(
url_user
,
"utf-8"
,
jsonUser
);
JSONObject
jsonobj_User
=
JSON
.
parseObject
(
result_User
);
String
authorizer_appid
=
jsonobj_User
.
getJSONObject
(
"authorization_info"
).
getString
(
"authorizer_appid"
);
token
=
jsonobj_User
.
getJSONObject
(
"authorization_info"
).
getString
(
"authorizer_access_token"
);
//获取授权方的帐号基本信息
String
paramInfo
=
"{\"component_appid\":\""
+
WeChat_client_id
+
"\",\"authorizer_appid\": \""
+
authorizer_appid
+
"\"}"
;
String
url_Info
=
WechatStaticData
.
USERINFO_PATH
+
form
.
getComponent_access_token
();
JSONObject
jsonInfo
=
JSONArray
.
parseObject
(
paramInfo
);
String
result_Info
=
HttpClientUtil
.
doPostW
(
url_Info
,
"utf-8"
,
jsonInfo
);
JSONObject
jsonobj_Info
=
JSON
.
parseObject
(
result_Info
);
//授权方昵称
userName
=
jsonobj_Info
.
getJSONObject
(
"authorizer_info"
).
getString
(
"nick_name"
);
userId
=
jsonobj_Info
.
getJSONObject
(
"authorizer_info"
).
getString
(
"user_name"
);
}
/**
* 网易号授权取的code,获取access_token值
...
...
@@ -275,7 +392,7 @@ public class UserController {
userName
=
jsonobj_token
.
getString
(
"tname"
);
userId
=
jsonobj_token
.
getString
(
"user_id"
);
}
accountRelationService
.
createCriteria
().
andEqualTo
(
"account
Name"
,
userName
);
accountRelationService
.
createCriteria
().
andEqualTo
(
"account
"
,
userId
);
UserAccountRelation
oneByCriteria
=
accountRelationService
.
selectOneByCriteria
();
if
(
oneByCriteria
==
null
){
UserAccountRelation
relation
=
new
UserAccountRelation
();
...
...
com.zrqx.resource/src/main/java/com/zrqx/resource/bg/util/Program.java
0 → 100644
浏览文件 @
52378c51
package
com
.
zrqx
.
resource
.
bg
.
util
;
import
java.io.StringReader
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.InputSource
;
import
com.zrqx.resource.bg.aes.WXBizMsgCrypt
;
public
class
Program
{
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
Program
.
class
);
public
static
void
main
(
String
[]
args
)
throws
Exception
{
//
// 第三方回复公众平台
//
// 需要加密的明文
String
encodingAesKey
=
"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG"
;
String
token
=
"pamtest"
;
String
timestamp
=
"1409304348"
;
String
nonce
=
"xxxxxx"
;
String
appId
=
"wx4f95e09cb7f4f354"
;
String
replyMsg
=
" 中文<xml><ToUserName><![CDATA[oia2TjjewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>"
;
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
String
mingwen
=
pc
.
encryptMsg
(
replyMsg
,
timestamp
,
nonce
);
System
.
out
.
println
(
"加密后: "
+
mingwen
);
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
dbf
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
dbf
.
setFeature
(
"http://xml.org/sax/features/external-general-entities"
,
false
);
dbf
.
setFeature
(
"http://xml.org/sax/features/external-parameter-entities"
,
false
);
dbf
.
setFeature
(
"http://apache.org/xml/features/nonvalidating/load-external-dtd"
,
false
);
dbf
.
setXIncludeAware
(
false
);
dbf
.
setExpandEntityReferences
(
false
);
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
StringReader
sr
=
new
StringReader
(
mingwen
);
InputSource
is
=
new
InputSource
(
sr
);
Document
document
=
db
.
parse
(
is
);
Element
root
=
document
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
NodeList
nodelist2
=
root
.
getElementsByTagName
(
"MsgSignature"
);
String
encrypt
=
nodelist1
.
item
(
0
).
getTextContent
();
String
msgSignature
=
nodelist2
.
item
(
0
).
getTextContent
();
String
format
=
"<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>"
;
String
fromXML
=
String
.
format
(
format
,
encrypt
);
// 公众平台发送消息给第三方,第三方处理
// 第三方收到公众号平台发送的消息
String
result2
=
pc
.
decryptMsg
(
msgSignature
,
timestamp
,
nonce
,
fromXML
);
logger
.
info
(
"++++++++++++++++++解密后明文:"
+
result2
);
System
.
out
.
println
(
"解密后明文: "
+
result2
);
}
}
com.zrqx.resource/src/main/java/com/zrqx/resource/commons/Redis.java
浏览文件 @
52378c51
...
...
@@ -27,7 +27,6 @@ import com.zrqx.core.util.JsonUtil.JsonUtil;
*/
@Component
public
class
Redis
{
private
static
final
String
FG_TOKEN
=
"y-token"
;
private
static
final
String
BG_TOKEN
=
"x-token"
;
...
...
@@ -50,6 +49,36 @@ public class Redis {
public
User
getUser
()
{
return
getInfoObjectRedis
(
getToken
(
BG_TOKEN
),
User
.
class
);
}
public
String
fmtObj
(
Object
obj
)
throws
IOException
{
return
obj
instanceof
String
?
obj
.
toString
():
JsonUtil
.
bean2Json
(
obj
);
}
/**
* 添加到redis
* @param token
* Key
* @param obj
* Value
* @param timeout
* 过期时间
* @param unit
* TimeUnitEnum 时间格式
* @throws IOException
*/
public
void
set
(
String
token
,
Object
obj
,
long
timeout
,
TimeUnit
unit
)
throws
IOException
{
stringRedisTemplate
.
opsForValue
().
set
(
token
,
fmtObj
(
obj
),
timeout
,
unit
);
}
public
void
set
(
String
token
,
Object
obj
,
long
timeout
)
throws
IOException
{
stringRedisTemplate
.
opsForValue
().
set
(
token
,
fmtObj
(
obj
),
timeout
,
TimeUnit
.
SECONDS
);
}
/**
* 添加到redis
* @param token Key
* @param obj Value
* @throws IOException
*/
public
void
set
(
String
token
,
Object
obj
)
throws
IOException
{
stringRedisTemplate
.
opsForValue
().
set
(
token
,
fmtObj
(
obj
));
}
/**
* 根据key删除redis中的数据
* @param key
...
...
@@ -107,18 +136,4 @@ public class Redis {
public
static
String
getFgToken
(){
return
getToken
(
FG_TOKEN
);
}
/**
* 获取前台登录用户信息
*
* @return
*/
public
String
fmtObj
(
Object
obj
)
throws
IOException
{
return
obj
instanceof
String
?
obj
.
toString
():
JsonUtil
.
bean2Json
(
obj
);
}
public
void
set
(
String
token
,
Object
obj
,
long
timeout
,
TimeUnit
unit
)
throws
IOException
{
stringRedisTemplate
.
opsForValue
().
set
(
token
,
fmtObj
(
obj
),
timeout
,
unit
);
}
public
void
set
(
String
token
,
Object
obj
,
long
timeout
)
throws
IOException
{
stringRedisTemplate
.
opsForValue
().
set
(
token
,
fmtObj
(
obj
),
timeout
,
TimeUnit
.
SECONDS
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论