package com.engine.salary.util; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.engine.salary.encrypt.AESEncryptUtil; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.util.db.IdGenerator; import org.apache.commons.lang3.StringUtils; import weaver.conn.RecordSet; import weaver.general.BaseBean; import weaver.rsa.security.RSA; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; public class SalaryTokenUtil { /** * 通过注册返回的OA系统公钥和秘钥获取token * * @param address OA地址 * @return * @throws NoSuchAlgorithmException * @throws KeyManagementException */ // public static Map testGetoken(String address) throws NoSuchAlgorithmException, KeyManagementException { // Map heads = new HashMap<>(); // Map datas = testRegist(address); // 注册接口返回的secrit私钥和spk公钥可以在第一次调用后,第三方系统保存起来,之后调用可以不用再调用这个注册接口 // //ECOLOGY返回的系统公钥 // String spk = (String) (datas.get("spk")); // RSA rsa = new RSA(); // //对秘钥进行加密传输,防止篡改数据 // String secret = rsa.encrypt(null, (String) (datas.get("secrit")), null, "utf-8", spk, false); // //封装参数到请求头 // heads.put("appid", APPID); // heads.put("secret", secret); // //调用ECOLOGY系统接口进行注册 // String data = post(address + "/api/ec/dev/auth/applytoken", null, heads); // System.out.println("=====testGetoken=====" + data); // return JSONObject.parseObject(data, new TypeReference>() { // }); // } /** * 注册第三方系统到OA系统,第一次用APPID获取到公钥spk和私钥secret,第三方系统可以保存,下次不用在请求注册接口 * * @param address OA地址 * @return * @throws NoSuchAlgorithmException * @throws KeyManagementException */ // public static Map testRegist(String address) throws NoSuchAlgorithmException, KeyManagementException { // Map heads = new HashMap<>(); // //获取当前异构系统RSA加密的公钥 // String cpk = new RSA().getRSA_PUB(); // //封装参数到请求头 // heads.put("appid", APPID); // heads.put("cpk", cpk); // //调用ECOLOGY系统接口进行注册 // String data = post(address + "/api/ec/dev/auth/regist", null, heads); // System.out.println("=====testRegist=====" + data); // return JSONObject.parseObject(data, new TypeReference>() { // }); // } /** * 第一次获取Token,需要先注册 * * @return */ public static Map GetToken(String uid) { uid = AESEncryptUtil.decrypt4SalaryBill(uid); Map heads = new HashMap<>(); if (StringUtils.isBlank(uid)) { return heads; } BaseBean baseBean = new BaseBean(); RecordSet rs = new RecordSet(); Map resultMap = new HashMap<>(); // 获取appid的id String appidId = baseBean.getPropValue("hrmSalaryBillToken", "appid_id"); String ip = baseBean.getPropValue("hrmSalaryBillToken", "ip"); rs.execute("select APPID from ECOLOGY_BIZ_EC where id =" + appidId); // 获取appid String appid =""; if (rs.next() && StringUtils.isNotEmpty(rs.getString("APPID"))) { appid = rs.getString("APPID"); } else { return resultMap; } String sql= " SELECT conf_value FROM hrsa_salary_sys_conf t WHERE delete_type = 0 AND conf_key = 'SALARY_TOKEN_SECRET'"; rs.execute(sql); String secret = ""; if (rs.next() && StringUtils.isNotEmpty(rs.getString("conf_value"))) { // 从数据库中拿secret secret = rs.getString("conf_value"); } else { // 注册获取secret // 获取当前异构系统RSA加密的公钥 String cpk = new RSA().getRSA_PUB(); //封装参数到请求头 heads.put("appid", appid); heads.put("cpk", cpk); // 调用ECOLOGY系统接口进行注册 String data = post("http://" + ip + "/api/ec/dev/auth/regist", null, heads); Map datas = JSONObject.parseObject(data, new TypeReference>() {}); // ECOLOGY返回的系统公钥 String spk = (String) (datas.get("spk")); RSA rsa = new RSA(); // 对秘钥进行加密传输,防止篡改数据 secret = rsa.encrypt(null, (String) (datas.get("secrit")), null, "utf-8", spk, false); // secret存库 String date = SalaryDateUtil.getFormatLocalDateTime(LocalDateTime.now()); sql = String.format("insert into hrsa_salary_sys_conf(id, conf_key, conf_value, title, module, order_weight, delete_type, create_time, update_time) values (%s,'%s','%s','%s','%s',%s,%s,'%s','%s')", IdGenerator.generate(), "SALARY_TOKEN_SECRET", secret, "token", "basic",0,0,date,date); rs.execute(sql); // 保存spk sql = String.format("insert into hrsa_salary_sys_conf(id, conf_key, conf_value, title, module, order_weight, delete_type, create_time, update_time) values (%s,'%s','%s','%s','%s',%s,%s,'%s','%s')", IdGenerator.generate(), "SALARY_TOKEN_SPK", spk, "spk", "basic",0,0,date,date); rs.execute(sql); } //封装参数到请求头 heads.put("appid", appid); heads.put("secret", secret); //调用ECOLOGY系统接口进行注册 String data2 = post("http://" + ip + "/api/ec/dev/auth/applytoken", null, heads); // 通过第一步注册许可时返回spk公钥对userid进行加密生成的密文 sql= " SELECT conf_value FROM hrsa_salary_sys_conf t WHERE delete_type = 0 AND conf_key = 'SALARY_TOKEN_SPK'"; rs.execute(sql); if (rs.next()){ String spk = rs.getString("conf_value"); // 对uid进行加密 RSA rsa = new RSA(); String encryptUid = rsa.encrypt(null, uid.toString(), null, "utf-8", spk, false); String token = (String)JSONObject.parseObject(data2, new TypeReference>() {}).get("token"); resultMap.put("userid", encryptUid); resultMap.put("token", token); resultMap.put("appid",appid); return resultMap; } else { throw new SalaryRunTimeException("spk不存在"); } } /** * 此方法仅供参考,第三方系统可采用自己的方式调用http接口 * * @param path 请求路径 * @param data 请求参数 * @return */ public static String post(String path, Map params, Map data) { try { String str = ""; // if (params != null) { // StringBuilder stringBuilder = new StringBuilder("?"); // for (Map.Entry entry : params.entrySet()) { // stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); // } // if (stringBuilder.length() > 1) // path += stringBuilder.substring(0, stringBuilder.length() - 1); // } URL url = new URL(path); //打开和url之间的连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // PrintWriter out = null; // 请求参数 编码为 utf-8 //请求方式 conn.setRequestMethod("POST"); //设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); if (data != null) { for (Map.Entry entry : data.entrySet()) { conn.setRequestProperty(entry.getKey(), entry.getValue()); } } //设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个 //最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet, //post与get的 不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。 conn.setDoOutput(true); conn.setDoInput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "utf-8"); if (params != null) { out.write(mapToStr(params)); } //缓冲数据 out.flush(); out.close(); //获取URLConnection对象对应的输入流 InputStream is = conn.getInputStream(); //构造一个字符流缓存 BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8")); String result = ""; while ((str = br.readLine()) != null) { result = str; } //关闭流 is.close(); //断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。 //固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。 conn.disconnect(); return result; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将Map转换成字符串参数,用于POST GET 请求 * * @param map * @return */ public static String mapToStr(Map map) { StringBuilder stringBuilder = new StringBuilder(); if (map != null) { for (Map.Entry entry : map.entrySet()) { stringBuilder.append(entry.getKey()); if (entry.getValue() != null) { stringBuilder.append("=").append(entry.getValue()); } stringBuilder.append("&"); } } if (stringBuilder.length() > 0) { return stringBuilder.substring(0, stringBuilder.length() - 1); } return null; } }