diff --git a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/mservice/ApiService.java b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/mservice/ApiService.java index 76f3d71..46a592c 100644 --- a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/mservice/ApiService.java +++ b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/mservice/ApiService.java @@ -71,21 +71,26 @@ import java.util.stream.Collectors; */ public class ApiService { private static final Log logger = LogFactory.getLog(ApiService.class); - private static final String APP_KEY = "22564a240d3140d0b15582aca71a748c"; + + // BIP测试环境AppKey + // private static final String APP_KEY = "22564a240d3140d0b15582aca71a748c"; + + // BIP生产环境AppKey + // private static final String APP_KEY = "e9ac4d8b14ea48c887634289cc5ca828"; private static final String API_ENDPOINT = "/iuap-api-auth/open-auth/selfAppAuth/getAccessToken"; private static final RestTemplate restTemplate = new RestTemplate(); - public static String getBIPToken(String domainName) { + public static String getBIPToken(String domainName, String appKey, String appSecret) { String token = "获取失败"; try { String timestamp = Long.toString(System.currentTimeMillis()); - String signature = generateSignature("appKey" + APP_KEY + "timestamp" + timestamp); + String signature = generateSignature("appKey" + appKey + "timestamp" + timestamp, appSecret); logger.info("getBIPToken → 签名: {}", signature); // URL with parameters String urlString = String.format( domainName + API_ENDPOINT + "?appKey=%s×tamp=%s&signature=%s", - APP_KEY, timestamp, signature + appKey, timestamp, signature ); URL url = new URL(urlString); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); @@ -158,10 +163,10 @@ public class ApiService { HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } - private static String generateSignature(String toSign) { + private static String generateSignature(String toSign, String appSecret) { try { // 计算 HmacSHA256 签名 - byte[] hmacData = computeHmacSha256(toSign); + byte[] hmacData = computeHmacSha256(toSign, appSecret); // Base64 编码 String base64Encoded = Base64.getEncoder().encodeToString(hmacData); @@ -174,8 +179,12 @@ public class ApiService { } } - private static byte[] computeHmacSha256(String data) throws Exception { - SecretKeySpec secretKey = new SecretKeySpec("79f0b7daa428c1abd9272565dbc65486ab565c80".getBytes(StandardCharsets.UTF_8), "HmacSHA256"); + private static byte[] computeHmacSha256(String data, String appSecret) throws Exception { + // BIP测试环境appSecret +// SecretKeySpec secretKey = new SecretKeySpec("79f0b7daa428c1abd9272565dbc65486ab565c80".getBytes(StandardCharsets.UTF_8), "HmacSHA256"); + + // BIP生产环境appSecret + SecretKeySpec secretKey = new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(secretKey); return mac.doFinal(data.getBytes(StandardCharsets.UTF_8)); @@ -194,7 +203,7 @@ public class ApiService { String billMark = dynamic.getDataEntityType().getName(); DynamicObject[] objects = BusinessDataServiceHelper.load("shkd_apimapping", "id,billno," + - "shkd_name,shkd_sourcenumber,shkd_domainname,shkd_token,shkd_url,shkd_bodytype," + + "shkd_name,shkd_sourcenumber,shkd_domainname,shkd_appkey,shkd_appsecret,shkd_token,shkd_url,shkd_bodytype," + "shkd_sourcebill,shkd_targetsystem,entryentity,entryentity.shkd_tarfield,entryentity.shkd_tartier," + "entryentity.shkd_tartype,entryentity.shkd_parentfield,entryentity.shkd_soufield,entryentity.shkd_defaultdata," + "entryentity.shkd_required,entryentity.shkd_remarks,shkd_submiturl", @@ -204,7 +213,9 @@ public class ApiService { // 获取token String domainName = objects[0].getString("shkd_domainname"); - String token = ApiService.getBIPToken(domainName); + String appKey = objects[0].getString("shkd_appkey"); + String appSecret = objects[0].getString("shkd_appsecret"); + String token = ApiService.getBIPToken(domainName, appKey, appSecret); logger.info("获取token:{}", token); String saveUrl = objects[0].getString("shkd_url"); @@ -1028,4 +1039,4 @@ public class ApiService { } } } -} +} \ No newline at end of file diff --git a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/CA/InfoSecService.java b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/CA/InfoSecService.java index 408cf00..e1b187e 100644 --- a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/CA/InfoSecService.java +++ b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/CA/InfoSecService.java @@ -1,46 +1,30 @@ package shkd.sys.sys.plugin.CA; -import cn.com.infosec.netsign.agent.NetSignAgent; -import cn.com.infosec.netsign.agent.NetSignResult; - -import java.io.InputStream; -import java.security.cert.X509Certificate; -import java.util.Map; -import java.util.Properties; - -import kd.bos.ca.bean.VerifySignResult; -import kd.bos.dataentity.serialization.SerializationUtils; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import kd.bos.ca.AbstractCAService; +import kd.bos.ca.bean.VerifySignResult; +import kd.bos.dataentity.entity.DynamicObject; import kd.bos.logging.Log; import kd.bos.logging.LogFactory; +import kd.bos.orm.query.QCP; +import kd.bos.orm.query.QFilter; +import kd.bos.servicehelper.BusinessDataServiceHelper; +import kd.bos.servicehelper.user.UserServiceHelper; +import okhttp3.*; + +import java.io.IOException; +import java.util.Map; /** * @description: CA服务 **/ public class InfoSecService extends AbstractCAService { private static Log log = LogFactory.getLog(InfoSecService.class); - private static Properties properties; private static boolean isInitialize; - static { - initProperties(); - } - - /** - * 初始化 - */ - private static void initProperties() { - if (properties == null) { - try (InputStream in = InfoSecService.class.getResourceAsStream("/resources/InfoSecConfig.properties")) { - properties = new Properties(); - properties.load(in); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("信安世纪服务配置文件初始化失败:" + e.getMessage()); - } - } - } + private static final OkHttpClient client = new OkHttpClient(); /** * @param signData 签名信息 @@ -52,29 +36,70 @@ public class InfoSecService extends AbstractCAService { @Override public VerifySignResult verifySign(String signData, String cleartext, String publicKey, Map caConfig) { log.info("验签开始"); + log.info("验签参数:\nsignData:{}\ncleartext:{}\npublicKey:{}\ncaConfig:{}", signData, cleartext, publicKey, caConfig); VerifySignResult result = new VerifySignResult(); - try { - /** - * 虽然能获取到苍穹系统上的配置,并构造ResourceBundle对象,但是信安世纪的服务只能初始化一次。感觉有点坑 - * 服务只能初始化一次。再次调用NetSignAgent.initialize不会生效。所以修改配置后只能重启服务。。。 - */ - if (!isInitialize) { - properties.putAll(caConfig); - InfoSecResourceBundle resourceBundle = new InfoSecResourceBundle(properties); - NetSignAgent.initialize(resourceBundle); - isInitialize = Boolean.TRUE; - } - X509Certificate certificate = NetSignAgent.generateCertificate(publicKey.getBytes()); - NetSignResult netSignResult = NetSignAgent.rawVerify(cleartext.getBytes(), signData, "SHA1", null, certificate); - log.info(SerializationUtils.toJsonString(netSignResult)); - result.setSuccess(true); - result.setMessage("验签通过。"); - } catch (Exception e) { - log.error(e); + long userId = UserServiceHelper.getCurrentUserId();//获取当前登录对象的Id + DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(userId, "bos_user"); + DynamicObject[] objects = BusinessDataServiceHelper.load("bd_usercredentials", "id,number,publickey,uname", new QFilter("uname", QCP.equals, dynamicObject.getString("name")).toArray()); + if (objects.length == 0) { result.setSuccess(false); - result.setMessage("验签失败:" + e.getMessage()); + result.setMessage("验签失败。"); + return result; + } else { + String puKey = objects[0].getString("publickey"); + if (publicKey.equals(puKey)) { + try { + String response = verifyPkcs7(cleartext, signData, "" + System.currentTimeMillis()); + JSONObject jsonObject = JSON.parseObject(response); + String code = jsonObject.getString("code"); + if ("200".equals(code)) { + result.setSuccess(true); + result.setMessage("验签通过。"); + } else { + result.setSuccess(false); + result.setMessage("验签失败。"); + } + log.info("验签响应: " + response); + + } catch (Exception e) { + log.error(e); + result.setSuccess(false); + result.setMessage("验签失败:" + e.getMessage()); + } + return result; + } else { + result.setSuccess(false); + result.setMessage("验签失败,签名人员和验签人员不同"); + log.info("验签失败,签名人员和验签人员不同"); + return result; + } + } + } + + private String verifyPkcs7(String toSign, String signedData, String reqId) throws IOException { + RequestBody formBody = new FormBody.Builder() + .add("projectId", "CTJD") + .add("toSign", toSign) + .add("signedData", signedData) + .add("version", "1") + .add("opType", "验签") + .add("reqId", reqId) + .build(); + log.info("POST请求开始,请求参数:{}", formBody); + + Request request = new Request.Builder() + .url("http://10.1.6.123:8080/sign-gw/api/signature/verifyPkcs7") + .post(formBody) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (response.isSuccessful()) { + return response.body().string(); + } else { + log.error("POST请求未成功,响应码: " + response.code()); + return "POST请求未成功"; + } } - return result; } } diff --git a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/api/PayBillApiSavePlugin.java b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/api/PayBillApiSavePlugin.java index 2152602..f4c3cd1 100644 --- a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/api/PayBillApiSavePlugin.java +++ b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/api/PayBillApiSavePlugin.java @@ -75,6 +75,7 @@ public class PayBillApiSavePlugin implements ApiSavePlugin { map.put("payeeformid", "other"); } + // 如果为供应商或者客户 if ("bd_supplier".equals(payeetype) || "bd_customer".equals(payeetype)) { logger.info("收款人ID:{}", map.get("payeenumber")); DynamicObject[] objects = BusinessDataServiceHelper.load(payeetype.toString(), "id,number,name,societycreditcode", new QFilter("societycreditcode", QCP.equals, map.get("payeenumber").toString()).toArray()); @@ -86,6 +87,16 @@ public class PayBillApiSavePlugin implements ApiSavePlugin { //收款人编码 objectNumber = map.get("payeenumber").toString(); } + } else if ("bos_user".equals(payeetype)) { + DynamicObject[] objects = BusinessDataServiceHelper.load(payeetype.toString(), "id,number,username", new QFilter("username", QCP.equals, map.get("payeenumber").toString()).toArray()); + if (objects.length > 0) { + map.put("payeenumber", objects[0].getString("number")); + //收款人编码 + objectNumber = objects[0].getString("number"); + } else { + //收款人编码 + objectNumber = map.get("payeenumber").toString(); + } } else { //收款人编码 objectNumber = map.get("payeenumber").toString(); diff --git a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiMappingBillPlugin.java b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiMappingBillPlugin.java index ce7cc61..2c0752d 100644 --- a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiMappingBillPlugin.java +++ b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiMappingBillPlugin.java @@ -64,62 +64,10 @@ public class ApiMappingBillPlugin extends AbstractFormPlugin implements Plugin { } DynamicObject dataEntity = this.getModel().getDataEntity(true); - // 获取想要推送单据编码 - String billNumber = dataEntity.getString("shkd_sourcenumber"); - logger.info("获取推送单据编码 → billNumber:{}", billNumber); - // 获取想要推送单据类型 - String billMark = dataEntity.getDynamicObject("shkd_sourcebill").getString("number"); - logger.info("获取推送单据类型 → billMark:{}", billMark); - - - DynamicObject billObject; - switch (billMark) { - // 付款处理 - case "cas_paybill": - DynamicObject[] objects1 = BusinessDataServiceHelper.load("cas_paybill", - "id,billno,actpayamt,entry,entry.e_expenseitem,entry.e_remark,settletype,payeebanknum," + - "payeetype,payeenumber,payeracctbank,payeebank,payeebankname,paymenttype,org,bizdate,description," + - "shkd_pushstatus,shkd_businessnumber,shkd_businessid,shkd_businessname,billstatus,bankpaystatus" - , new QFilter("billno", QCP.equals, billNumber).toArray()); - billObject = objects1[0]; - logger.info("获取付款处理推送对象 → billObject:{}", billObject); - break; - // 收款处理 - case "cas_recbill": - DynamicObject[] objects2 = BusinessDataServiceHelper.load("cas_recbill", - "id,billno,entry,entry.e_expenseitem,settletype,entry.e_remark,receivingtype," + - "payertype,org,bizdate,accountbank,payernumber,actrecamt,txt_description,shkd_pushstatus," + - "shkd_businessnumber,shkd_businessid,shkd_businessname,billstatus" - , new QFilter("billno", QCP.equals, billNumber).toArray()); - billObject = objects2[0]; - logger.info("获取收款处理推送对象 → billObject:{}", billObject); - break; - // 银企交易明细查询 - case "bei_transdetail_cas": - DynamicObject[] objects3 = BusinessDataServiceHelper.load("bei_transdetail_cas", - "id,billno,bizdate,oppbank,oppunit,accountbank,description,company,oppbanknumber," + - "bankdetailno,transbalance,description,debitamount,creditamount,shkd_pushstatus," + - "shkd_businessnumber,shkd_businessid,shkd_businessname" - , new QFilter("billno", QCP.equals, billNumber).toArray()); - billObject = objects3[0]; - logger.info("获取银企交易明细查询推送对象 → billObject:{}", billObject); - break; - // 电子回单查询 - case "bei_elecreceipt": - DynamicObject[] objects4 = BusinessDataServiceHelper.load("bei_elecreceipt", - "id,billno,shkd_pushstatus,fileserverurl,bizdate,oppbankname,description,company,oppbanknumber," + - "detaildatetime,accountbank,amount,use,debitamount,creditamount,detailid,uploadfilename," + - "shkd_businessnumber,shkd_businessid,shkd_businessname,filepath" - , new QFilter("billno", QCP.equals, billNumber).toArray()); - billObject = objects4[0]; - logger.info("获取银企交易明细查询推送对象 → billObject:{}", billObject); - break; - default: - return; - } // 生成JSON if ("shkd_generatejson".equals(itemKey)) { + DynamicObject billObject = getDynamicObject(dataEntity); if (billObject == null) { this.getView().showTipNotification("未查询到具体推送单据"); return; @@ -131,12 +79,14 @@ public class ApiMappingBillPlugin extends AbstractFormPlugin implements Plugin { List dynamicObjects = new ArrayList<>(); if ("shkd_testapi".equals(itemKey)) { + DynamicObject billObject = getDynamicObject(dataEntity); String result = ApiService.paymentSlipsJson(billObject, "BIP", dynamicObjects, null); SaveServiceHelper.save(dynamicObjects.toArray(new DynamicObject[0])); this.getView().showTipNotification("返回结果:" + result); } if ("shkd_pushjson".equals(itemKey)) { + DynamicObject billObject = getDynamicObject(dataEntity); String requestBody = codeEdit.getText(); String result = ApiService.paymentSlipsJson(billObject, "BIP", dynamicObjects, requestBody); SaveServiceHelper.save(dynamicObjects.toArray(new DynamicObject[0])); @@ -144,6 +94,7 @@ public class ApiMappingBillPlugin extends AbstractFormPlugin implements Plugin { } if ("shkd_hitback".equals(itemKey)) { + DynamicObject billObject = getDynamicObject(dataEntity); String result = ApiService.paymentSlipsJson(billObject, "BIPNO", dynamicObjects, null); SaveServiceHelper.save(dynamicObjects.toArray(new DynamicObject[0])); this.getView().showTipNotification("返回结果:" + result); @@ -152,7 +103,10 @@ public class ApiMappingBillPlugin extends AbstractFormPlugin implements Plugin { if ("shkd_gettoken".equals(itemKey)) { //域名 String domainName = dataEntity.getString("shkd_domainname"); - String token = ApiService.getBIPToken(domainName); + String appKey = dataEntity.getString("shkd_appkey"); + String appSecret = dataEntity.getString("shkd_appsecret"); + + String token = ApiService.getBIPToken(domainName, appKey, appSecret); this.getModel().setValue("shkd_token", token); } } @@ -242,4 +196,63 @@ public class ApiMappingBillPlugin extends AbstractFormPlugin implements Plugin { sb.append(" "); // 使用4个空格作为缩进 } } + + + private DynamicObject getDynamicObject(DynamicObject dataEntity) { + + // 获取想要推送单据编码 + String billNumber = dataEntity.getString("shkd_sourcenumber"); + logger.info("获取推送单据编码 → billNumber:{}", billNumber); + // 获取想要推送单据类型 + String billMark = dataEntity.getDynamicObject("shkd_sourcebill").getString("number"); + logger.info("获取推送单据类型 → billMark:{}", billMark); + + + DynamicObject billObject; + switch (billMark) { + // 付款处理 + case "cas_paybill": + DynamicObject[] objects1 = BusinessDataServiceHelper.load("cas_paybill", + "id,billno,actpayamt,entry,entry.e_expenseitem,entry.e_remark,settletype,payeebanknum," + + "payeetype,payeenumber,payeracctbank,payeebank,payeebankname,paymenttype,org,bizdate,description," + + "shkd_pushstatus,shkd_businessnumber,shkd_businessid,shkd_businessname,billstatus,bankpaystatus" + , new QFilter("billno", QCP.equals, billNumber).toArray()); + billObject = objects1[0]; + logger.info("获取付款处理推送对象 → billObject:{}", billObject); + break; + // 收款处理 + case "cas_recbill": + DynamicObject[] objects2 = BusinessDataServiceHelper.load("cas_recbill", + "id,billno,entry,entry.e_expenseitem,settletype,entry.e_remark,receivingtype," + + "payertype,org,bizdate,accountbank,payernumber,actrecamt,txt_description,shkd_pushstatus," + + "shkd_businessnumber,shkd_businessid,shkd_businessname,billstatus" + , new QFilter("billno", QCP.equals, billNumber).toArray()); + billObject = objects2[0]; + logger.info("获取收款处理推送对象 → billObject:{}", billObject); + break; + // 银企交易明细查询 + case "bei_transdetail_cas": + DynamicObject[] objects3 = BusinessDataServiceHelper.load("bei_transdetail_cas", + "id,billno,bizdate,oppbank,oppunit,accountbank,description,company,oppbanknumber," + + "bankdetailno,transbalance,description,debitamount,creditamount,shkd_pushstatus," + + "shkd_businessnumber,shkd_businessid,shkd_businessname" + , new QFilter("billno", QCP.equals, billNumber).toArray()); + billObject = objects3[0]; + logger.info("获取银企交易明细查询推送对象 → billObject:{}", billObject); + break; + // 电子回单查询 + case "bei_elecreceipt": + DynamicObject[] objects4 = BusinessDataServiceHelper.load("bei_elecreceipt", + "id,billno,shkd_pushstatus,fileserverurl,bizdate,oppbankname,description,company,oppbanknumber," + + "detaildatetime,accountbank,amount,use,debitamount,creditamount,detailid,uploadfilename," + + "shkd_businessnumber,shkd_businessid,shkd_businessname,filepath" + , new QFilter("billno", QCP.equals, billNumber).toArray()); + billObject = objects4[0]; + logger.info("获取银企交易明细查询推送对象 → billObject:{}", billObject); + break; + default: + billObject = null; + } + return billObject; + } } \ No newline at end of file diff --git a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiTestBillPlugin.java b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiTestBillPlugin.java index 0b8e7a9..0d2ed0b 100644 --- a/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiTestBillPlugin.java +++ b/sys/shkd-sys-sys/src/main/java/shkd/sys/sys/plugin/form/ApiTestBillPlugin.java @@ -32,9 +32,9 @@ public class ApiTestBillPlugin extends AbstractBillPlugIn implements Plugin { String key = evt.getItemKey(); if ("shkd_token".equals(key)) { - String url = this.getModel().getValue("shkd_url").toString(); - String token = ApiService.getBIPToken(url); - this.getView().showTipNotification(token == null ? "获取token为空" :token); +// String url = this.getModel().getValue("shkd_url").toString(); +// String token = ApiService.getBIPToken(url); +// this.getView().showTipNotification(token == null ? "获取token为空" :token); } if ("shkd_api".equals(key)) {