丽知:配置钉钉回调

This commit is contained in:
zhengyf 2024-10-30 22:04:18 +08:00
parent a51094efe8
commit 4bdbe61e0e
7 changed files with 74 additions and 52 deletions

View File

@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map; import java.util.Map;
/** /**
@ -27,7 +28,8 @@ public class CallBackController {
@RequestMapping(value = "res") @RequestMapping(value = "res")
@ResponseBody @ResponseBody
public Map<String, String> res(@RequestParam(value = "msg_signature", required = false) String msg_signature, public Map<String, String> res(HttpServletRequest request,
@RequestParam(value = "msg_signature", required = false) String msg_signature,
@RequestParam(value = "timestamp", required = false) String timeStamp, @RequestParam(value = "timestamp", required = false) String timeStamp,
@RequestParam(value = "nonce", required = false) String nonce, @RequestParam(value = "nonce", required = false) String nonce,
@RequestBody(required = false) JSONObject json) { @RequestBody(required = false) JSONObject json) {

View File

@ -1,6 +1,7 @@
package com.hzya.frame.plugin.lets.dingtalk.callback.service; package com.hzya.frame.plugin.lets.dingtalk.callback.service;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.hzya.frame.plugin.lets.dingtalk.vo.DingCallbackCrypto;
import java.util.Map; import java.util.Map;

View File

@ -21,7 +21,7 @@ public class CallBackServiceImpl implements CallBackService {
private String token; private String token;
@Value("${DING.call_back_aes_key}") @Value("${DING.call_back_aes_key}")
private String aes_key; private String aes_key;
@Value("${DING.APPKEY}") @Value("${DING.call_back_appkey}")
private String corpId; private String corpId;
@Override @Override
@ -43,15 +43,22 @@ public class CallBackServiceImpl implements CallBackService {
String eventType = eventJson.getString("EventType"); String eventType = eventJson.getString("EventType");
// 4. 根据EventType分类处理 // 4. 根据EventType分类处理
if ("check_url".equals(eventType)) { if (eventJson.getString("processCode") != null) {
// 测试回调url的正确性 switch (eventJson.getString("processCode")) {
logger.info("测试回调url的正确性"); case "PROC-EC6B5BD2-DE3C-456E-9591-6F7B377E39E4":
} else if ("bpms_instance_change".equals(eventType)) { logger.info("采购付款申请(新) -> PROC-EC6B5BD2-DE3C-456E-9591-6F7B377E39E4");
// 处理通讯录用户增加事件 // outSourceBill(eventJson);//采购付款申请
logger.info("发生了:" + eventType + "事件"); break;
} else { case "PROC-285CCF2B-524F-4055-BE62-FC31F490C654":
// 添加其他已注册的 logger.info("采购付款申请(店群专用) -> PROC-285CCF2B-524F-4055-BE62-FC31F490C654");
logger.info("发生了:" + eventType + "事件"); // agencyBill(eventJson);//采购付款申请店群专用
break;
case "PROC-AC33FC85-FB44-49FC-B926-1D966AE3BBD2":
logger.info("采购付款申请(新) -> PROC-AC33FC85-FB44-49FC-B926-1D966AE3BBD2");
// transferBill(eventJson);//特殊业务处理
break;
}
} }
// 5. 返回success的加密数据 // 5. 返回success的加密数据

View File

@ -6,6 +6,9 @@ import com.aliyun.dingtalkworkflow_1_0.models.GetProcessCodeByNameResponse;
import com.dingtalk.api.response.OapiUserListidResponse; import com.dingtalk.api.response.OapiUserListidResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse; import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse; import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import org.apache.commons.codec.binary.Base64;
import java.util.UUID;
/** /**
* 获取审批钉盘空间信息,spaceId:20852670637 * 获取审批钉盘空间信息,spaceId:20852670637
@ -15,25 +18,25 @@ import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
* 采购付款申请店群专用 PROC-285CCF2B-524F-4055-BE62-FC31F490C654 25354973072 * 采购付款申请店群专用 PROC-285CCF2B-524F-4055-BE62-FC31F490C654 25354973072
*/ */
public class Test { public class Test {
public static void main(String[] args) throws Exception { // public static void main(String[] args) throws Exception {
String appKey="ding5qfifcktfqfjlem0"; // String appKey="ding5qfifcktfqfjlem0";
String appSecret="BVuLOy_K0F8f5np69VuBeKdb1zfwqhuPsAV49lNbYVbx5TnfSTHjwEcad9Vwzfq1"; // String appSecret="BVuLOy_K0F8f5np69VuBeKdb1zfwqhuPsAV49lNbYVbx5TnfSTHjwEcad9Vwzfq1";
//获取token //获取token
GetAccessTokenResponseBody tokenBody = DingTalkUtils.getTokenBody(appKey, appSecret); // GetAccessTokenResponseBody tokenBody = DingTalkUtils.getTokenBody(appKey, appSecret);
System.out.println(tokenBody.getAccessToken()); // System.out.println(tokenBody.getAccessToken());
//获取用户列表 //获取用户列表
// OapiUserListidResponse userIdList = DingTalkUtils.getUserIdList(tokenBody.getAccessToken()); // OapiUserListidResponse userIdList = DingTalkUtils.getUserIdList(tokenBody.getAccessToken());
// System.out.println(userIdList); // System.out.println(userIdList);
//根据手机号查询用户详情,userid:6715600736721738 //根据手机号查询用户详情,userid:6715600736721738
OapiV2UserGetbymobileResponse userByMobile = DingTalkUtils.getUserByMobile(tokenBody.getAccessToken(), "13783530043"); // OapiV2UserGetbymobileResponse userByMobile = DingTalkUtils.getUserByMobile(tokenBody.getAccessToken(), "13783530043");
System.out.println(userByMobile.getResult().getUserid()); // System.out.println(userByMobile.getResult().getUserid());
//查询用户详情,unionId:xXpSQXdGCyYNcQXxrgezOwiEiE //查询用户详情,unionId:xXpSQXdGCyYNcQXxrgezOwiEiE
OapiV2UserGetResponse userById = DingTalkUtils.getUserById(tokenBody.getAccessToken(), "6715600736721738"); // OapiV2UserGetResponse userById = DingTalkUtils.getUserById(tokenBody.getAccessToken(), "6715600736721738");
System.out.println(userById.getBody()); // System.out.println(userById.getBody());
//获取审批钉盘空间信息,spaceId:20852670637 //获取审批钉盘空间信息,spaceId:20852670637
// GetAttachmentSpaceResponse processDingPanSpaceInfo = DingTalkUtils.getProcessDingPanSpaceInfo(tokenBody.getAccessToken(), "6715600736721738"); // GetAttachmentSpaceResponse processDingPanSpaceInfo = DingTalkUtils.getProcessDingPanSpaceInfo(tokenBody.getAccessToken(), "6715600736721738");
@ -46,9 +49,11 @@ public class Test {
// System.out.println(processCode1.getBody().getResult().getProcessCode());//PROC-EC6B5BD2-DE3C-456E-9591-6F7B377E39E4 // System.out.println(processCode1.getBody().getResult().getProcessCode());//PROC-EC6B5BD2-DE3C-456E-9591-6F7B377E39E4
// GetProcessCodeByNameResponse processCode2 = DingTalkUtils.getProcessCode(tokenBody.getAccessToken(), "采购付款申请(店群专用)"); // GetProcessCodeByNameResponse processCode2 = DingTalkUtils.getProcessCode(tokenBody.getAccessToken(), "采购付款申请(店群专用)");
// System.out.println(processCode2.getBody().getResult().getProcessCode());//PROC-285CCF2B-524F-4055-BE62-FC31F490C654 // System.out.println(processCode2.getBody().getResult().getProcessCode());//PROC-285CCF2B-524F-4055-BE62-FC31F490C654
// }
public static void main(String[] args) {
String key = Base64.encodeBase64String(UUID.randomUUID().toString().replaceAll("-","").getBytes());
System.out.println(key);
}
}
} }

View File

@ -1,23 +1,32 @@
package com.hzya.frame.plugin.lets.dingtalk.vo; package com.hzya.frame.plugin.lets.dingtalk.vo;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.Permission; import java.security.Permission;
import java.security.PermissionCollection; import java.security.PermissionCollection;
import java.security.Security;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.security.Security;
import java.lang.reflect.Field;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
/**
* 钉钉开放平台加解密方法
* 在ORACLE官方网站下载JCE无限制权限策略文件
* JDK6的下载地址http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
* JDK7的下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
* JDK8的下载地址 https://www.oracle.com/java/technologies/javase-jce8-downloads.html
*/
public class DingCallbackCrypto { public class DingCallbackCrypto {
private static final Charset CHARSET = Charset.forName("utf-8"); private static final Charset CHARSET = Charset.forName("utf-8");
@ -42,6 +51,7 @@ public class DingCallbackCrypto {
* @param corpId 企业自建应用-事件订阅, 使用appKey * @param corpId 企业自建应用-事件订阅, 使用appKey
* 企业自建应用-注册回调地址, 使用corpId * 企业自建应用-注册回调地址, 使用corpId
* 第三方企业应用, 使用suiteKey * 第三方企业应用, 使用suiteKey
*
* @throws DingTalkEncryptException 执行失败请查看该异常的错误码和具体的错误信息 * @throws DingTalkEncryptException 执行失败请查看该异常的错误码和具体的错误信息
*/ */
public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException { public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException {
@ -197,7 +207,7 @@ public class DingCallbackCrypto {
public String getSignature(String token, String timestamp, String nonce, String encrypt) public String getSignature(String token, String timestamp, String nonce, String encrypt)
throws DingTalkEncryptException { throws DingTalkEncryptException {
try { try {
String[] array = new String[]{token, timestamp, nonce, encrypt}; String[] array = new String[] {token, timestamp, nonce, encrypt};
Arrays.sort(array); Arrays.sort(array);
System.out.println(JSON.toJSONString(array)); System.out.println(JSON.toJSONString(array));
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
@ -243,8 +253,8 @@ public class DingCallbackCrypto {
} }
public static byte[] int2Bytes(int count) { public static byte[] int2Bytes(int count) {
byte[] byteArr = new byte[]{(byte) (count >> 24 & 255), (byte) (count >> 16 & 255), (byte) (count >> 8 & 255), byte[] byteArr = new byte[] {(byte)(count >> 24 & 255), (byte)(count >> 16 & 255), (byte)(count >> 8 & 255),
(byte) (count & 255)}; (byte)(count & 255)};
return byteArr; return byteArr;
} }
@ -293,8 +303,8 @@ public class DingCallbackCrypto {
} }
private static char chr(int a) { private static char chr(int a) {
byte target = (byte) (a & 255); byte target = (byte)(a & 255);
return (char) target; return (char)target;
} }
} }
@ -332,11 +342,10 @@ public class DingCallbackCrypto {
} }
public DingTalkEncryptException(Integer exceptionCode) { public DingTalkEncryptException(Integer exceptionCode) {
super((String) msgMap.get(exceptionCode)); super((String)msgMap.get(exceptionCode));
this.code = exceptionCode; this.code = exceptionCode;
} }
} }
static { static {
try { try {
Security.setProperty("crypto.policy", "limited"); Security.setProperty("crypto.policy", "limited");
@ -345,27 +354,25 @@ public class DingCallbackCrypto {
} }
} }
private static void RemoveCryptographyRestrictions() throws Exception { private static void RemoveCryptographyRestrictions() throws Exception {
Class<?> jceSecurity = getClazz("javax.crypto.JceSecurity"); Class<?> jceSecurity = getClazz("javax.crypto.JceSecurity");
Class<?> cryptoPermissions = getClazz("javax.crypto.CryptoPermissions"); Class<?> cryptoPermissions = getClazz("javax.crypto.CryptoPermissions");
Class<?> cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission"); Class<?> cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission");
if (jceSecurity != null) { if (jceSecurity != null) {
setFinalStaticValue(jceSecurity, "isRestricted", false); setFinalStaticValue(jceSecurity, "isRestricted", false);
PermissionCollection defaultPolicy = (PermissionCollection) getFieldValue(jceSecurity, "defaultPolicy", (Object) null, PermissionCollection.class); PermissionCollection defaultPolicy = (PermissionCollection)getFieldValue(jceSecurity, "defaultPolicy", (Object)null, PermissionCollection.class);
if (cryptoPermissions != null) { if (cryptoPermissions != null) {
Map<?, ?> map = (Map) getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class); Map<?, ?> map = (Map)getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class);
map.clear(); map.clear();
} }
if (cryptoAllPermission != null) { if (cryptoAllPermission != null) {
Permission permission = (Permission) getFieldValue(cryptoAllPermission, "INSTANCE", (Object) null, Permission.class); Permission permission = (Permission)getFieldValue(cryptoAllPermission, "INSTANCE", (Object)null, Permission.class);
defaultPolicy.add(permission); defaultPolicy.add(permission);
} }
} }
} }
private static Class<?> getClazz(String className) { private static Class<?> getClazz(String className) {
Class clazz = null; Class clazz = null;
@ -376,20 +383,18 @@ public class DingCallbackCrypto {
return clazz; return clazz;
} }
private static void setFinalStaticValue(Class<?> srcClazz, String fieldName, Object newValue) throws Exception { private static void setFinalStaticValue(Class<?> srcClazz, String fieldName, Object newValue) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName); Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true); field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers"); Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true); modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & -17); modifiersField.setInt(field, field.getModifiers() & -17);
field.set((Object) null, newValue); field.set((Object)null, newValue);
} }
private static <T> T getFieldValue(Class<?> srcClazz, String fieldName, Object owner, Class<T> dstClazz) throws Exception { private static <T> T getFieldValue(Class<?> srcClazz, String fieldName, Object owner, Class<T> dstClazz) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName); Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true); field.setAccessible(true);
return dstClazz.cast(field.get(owner)); return dstClazz.cast(field.get(owner));
} }
} }

View File

@ -57,8 +57,9 @@ DING:
CorpId: dingc5b16c82b7f25e64acaaa37764f94726 CorpId: dingc5b16c82b7f25e64acaaa37764f94726
APIToken: c5530fb4faed387593ee17f4e6bb748d APIToken: c5530fb4faed387593ee17f4e6bb748d
#钉钉回调 #钉钉回调
call_back_token: q9llHUSJnD3br9iOSHcJh2I5qa4l3lau29vfv3Kwud9ExEKC1dWLQP2RQT9 call_back_token: lets123456789lets
call_back_aes_key: tMcQS7SdmvyeuFB6iKaxYG46WmbTfU2CjBDr3IRCqci call_back_aes_key: MDlmYTY2ODUzMTliNDhmZjg3ZTViNzc3MzYyZWI4MWM
call_back_appkey: ding5qfifcktfqfjlem0
#Client ID (原 AppKey 和 SuiteKey) #Client ID (原 AppKey 和 SuiteKey)
APPKEY: ding5qfifcktfqfjlem0 APPKEY: ding5qfifcktfqfjlem0
#Client Secret (原 AppSecret 和 SuiteSecret) #Client Secret (原 AppSecret 和 SuiteSecret)

View File

@ -49,8 +49,9 @@ DING:
CorpId: dingc5b16c82b7f25e64acaaa37764f94726 CorpId: dingc5b16c82b7f25e64acaaa37764f94726
APIToken: c5530fb4faed387593ee17f4e6bb748d APIToken: c5530fb4faed387593ee17f4e6bb748d
#钉钉回调 #钉钉回调
call_back_token: q9llHUSJnD3br9iOSHcJh2I5qa4l3lau29vfv3Kwud9ExEKC1dWLQP2RQT9 call_back_token: lets123456789lets
call_back_aes_key: tMcQS7SdmvyeuFB6iKaxYG46WmbTfU2CjBDr3IRCqci call_back_aes_key: MDlmYTY2ODUzMTliNDhmZjg3ZTViNzc3MzYyZWI4MWM
call_back_appkey: ding5qfifcktfqfjlem0
#Client ID (原 AppKey 和 SuiteKey) #Client ID (原 AppKey 和 SuiteKey)
APPKEY: ding5qfifcktfqfjlem0 APPKEY: ding5qfifcktfqfjlem0
#Client Secret (原 AppSecret 和 SuiteSecret) #Client Secret (原 AppSecret 和 SuiteSecret)