mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-04-21 19:45:09 +08:00
238 lines
8.9 KiB
Java
238 lines
8.9 KiB
Java
package com.jsowell.api.thirdparty;
|
||
|
||
import com.alibaba.fastjson2.JSONObject;
|
||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||
import com.google.common.collect.Maps;
|
||
import com.jsowell.common.annotation.Anonymous;
|
||
import com.jsowell.common.core.controller.BaseController;
|
||
import com.jsowell.common.exception.BusinessException;
|
||
import com.jsowell.common.util.JWTUtils;
|
||
import com.jsowell.common.util.StringUtils;
|
||
import com.jsowell.pile.thirdparty.CommonParamsDTO;
|
||
import com.jsowell.pile.vo.ThirdPartySecretInfoVO;
|
||
import com.jsowell.thirdparty.platform.util.Cryptos;
|
||
import com.jsowell.thirdparty.platform.util.GBSignUtils;
|
||
import com.jsowell.thirdparty.service.ThirdpartySecretInfoService;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.web.bind.annotation.RestController;
|
||
|
||
import java.lang.reflect.Field;
|
||
import java.lang.reflect.InvocationTargetException;
|
||
import java.lang.reflect.Method;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* 基础Controller
|
||
*/
|
||
@Anonymous
|
||
@RestController
|
||
public class ThirdPartyBaseController extends BaseController {
|
||
|
||
@Autowired
|
||
private ThirdpartySecretInfoService thirdpartySecretInfoService;
|
||
|
||
/**
|
||
* 验证token
|
||
*/
|
||
protected boolean verifyToken(String token) {
|
||
if (StringUtils.equals(token, "jsowellTest")) {
|
||
// 为了方便测试,token为jsowellTest校验通过
|
||
return true;
|
||
}
|
||
boolean result;
|
||
try {
|
||
result = JWTUtils.checkThirdPartyToken(token);
|
||
} catch (Exception e) {
|
||
result = false;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 解析DTO
|
||
* @param dto
|
||
* @param targetClass
|
||
* @return
|
||
* @param <T>
|
||
*/
|
||
protected <T> T parseParamsDTO(CommonParamsDTO dto, Class<T> targetClass) throws NoSuchFieldException, IllegalAccessException {
|
||
// 解密
|
||
String operatorId = StringUtils.isNotBlank(dto.getOperatorID()) ? dto.getOperatorID() : dto.getPlatformID();
|
||
ThirdPartySecretInfoVO secretInfoVO;
|
||
if (StringUtils.isNotBlank(dto.getPlatformType())) {
|
||
// type不为空,按照type查
|
||
secretInfoVO = thirdpartySecretInfoService.queryByThirdPlatformType(dto.getPlatformType());
|
||
}else {
|
||
secretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId);
|
||
}
|
||
// 通过operatorId 查出 operatorSecret
|
||
// ThirdPartySecretInfoVO secretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId);
|
||
if (secretInfoVO == null) {
|
||
throw new BusinessException("1", "无此对接平台");
|
||
}
|
||
|
||
String dataSecret = secretInfoVO.getOurDataSecret();
|
||
String dataSecretIv = secretInfoVO.getOurDataSecretIv();
|
||
|
||
// 解密data 获取参数中的OperatorSecret
|
||
String decrypt = Cryptos.decrypt(dto.getData(), dataSecret, dataSecretIv);
|
||
T t = JSONObject.parseObject(decrypt, targetClass);
|
||
|
||
// 校验是否有operatorId, 没有就set
|
||
verifyOperatorId(dto, t);
|
||
return t;
|
||
}
|
||
|
||
/**
|
||
* 获取OperatorId的值 verify
|
||
* @param t
|
||
* @return
|
||
* @throws NoSuchFieldException
|
||
* @throws IllegalAccessException
|
||
*/
|
||
private <T> void verifyOperatorId(CommonParamsDTO dto, T t) throws NoSuchFieldException, IllegalAccessException {
|
||
String targetFieldName = "operatorId";
|
||
String operatorId = (String) getFieldValueByObject(t, targetFieldName);
|
||
if (StringUtils.isBlank(operatorId)) {
|
||
setFieldValueByFieldName(t, targetFieldName, dto.getOperatorID());
|
||
}
|
||
}
|
||
|
||
private <T> void setFieldValueByFieldName(T t, String targetFieldName, Object value) {
|
||
// 获取该对象的class
|
||
Class<? extends Object> tClass = t.getClass();
|
||
// 获取所有的属性数组
|
||
Field[] fields = tClass.getDeclaredFields();
|
||
|
||
for (Field field : fields) {
|
||
// 属性名称
|
||
String currentFieldName = "";
|
||
try {
|
||
boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class);
|
||
if (has_JsonProperty) {
|
||
currentFieldName = field.getAnnotation(JsonProperty.class).value();
|
||
} else {
|
||
currentFieldName = field.getName();
|
||
}
|
||
// 忽略大小写对比
|
||
if (currentFieldName.equalsIgnoreCase(targetFieldName)) {
|
||
// 取消语言访问检查
|
||
field.setAccessible(true);
|
||
// 给变量赋值
|
||
field.set(t, value);
|
||
return;
|
||
}
|
||
} catch (Exception e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 使用反射获取字段值
|
||
*/
|
||
private <T> Object getFieldValueByObject(T t, String targetFieldName) {
|
||
// 获取该对象的class
|
||
Class<? extends Object> tClass = t.getClass();
|
||
// 获取所有的属性数组
|
||
Field[] fields = tClass.getDeclaredFields();
|
||
/**
|
||
* 这里只需要 id 这个属性,所以直接取 fields[0] 这
|
||
* 一个,如果id不是排在第一位,自己取相应的位置,
|
||
* 如果有需要,可以写成for循环,遍历全部属性
|
||
*/
|
||
|
||
for (Field field : fields) {
|
||
// 属性名称
|
||
String currentFieldName = "";
|
||
// 获取属性上面的注解 import com.fasterxml.jackson.annotation.JsonProperty;
|
||
/**
|
||
* 举例: @JsonProperty("roleIds")
|
||
* private String roleIds;
|
||
*/
|
||
try {
|
||
boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class);
|
||
if (has_JsonProperty) {
|
||
currentFieldName = field.getAnnotation(JsonProperty.class).value();
|
||
} else {
|
||
currentFieldName = field.getName();
|
||
}
|
||
// 忽略大小写对比
|
||
if (currentFieldName.equalsIgnoreCase(targetFieldName)) {
|
||
field.setAccessible(true);
|
||
currentFieldName = currentFieldName.replaceFirst(currentFieldName.substring(0, 1), currentFieldName.substring(0, 1).toUpperCase());
|
||
//整合出 getId() 属性这个方法
|
||
Method m = tClass.getMethod("get" + currentFieldName);
|
||
return m.invoke(t);
|
||
}
|
||
} catch (SecurityException e) {
|
||
// 安全性异常
|
||
e.printStackTrace();
|
||
} catch (IllegalArgumentException e) {
|
||
// 非法参数
|
||
e.printStackTrace();
|
||
} catch (IllegalAccessException | NoSuchMethodException e) {
|
||
// 无访问权限
|
||
e.printStackTrace();
|
||
} catch (InvocationTargetException e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 校验签名
|
||
*
|
||
* verifySignature
|
||
*/
|
||
protected boolean verifySignature(CommonParamsDTO dto) {
|
||
return this.verifySignature(dto, null);
|
||
}
|
||
|
||
protected boolean verifySignature(CommonParamsDTO dto, String signSecret) {
|
||
// 查询密钥
|
||
String operatorId = StringUtils.isNotBlank(dto.getOperatorID()) ? dto.getOperatorID() : dto.getPlatformID();
|
||
ThirdPartySecretInfoVO secretInfoVO;
|
||
if (StringUtils.isNotBlank(dto.getPlatformType())) {
|
||
// type不为空,按照type查
|
||
secretInfoVO = thirdpartySecretInfoService.queryByThirdPlatformType(dto.getPlatformType());
|
||
}else {
|
||
secretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId);
|
||
}
|
||
if (secretInfoVO == null) {
|
||
throw new BusinessException("1", "无此对接平台");
|
||
}
|
||
// 校验签名,使用响应方的密钥
|
||
if (StringUtils.isBlank(signSecret)) {
|
||
signSecret = secretInfoVO.getOurSigSecret();
|
||
}
|
||
Map<String, String> map = Maps.newLinkedHashMap();
|
||
String operatorID = dto.getOperatorID();
|
||
if (StringUtils.isNotBlank(operatorID)) {
|
||
map.put("OperatorID", operatorID);
|
||
}
|
||
String platformID = dto.getPlatformID();
|
||
if (StringUtils.isNotBlank(platformID)) {
|
||
map.put("PlatformID", platformID);
|
||
}
|
||
String data = dto.getData();
|
||
if (StringUtils.isNotBlank(data)) {
|
||
map.put("Data", data);
|
||
}
|
||
String timeStamp = dto.getTimeStamp();
|
||
if (StringUtils.isNotBlank(timeStamp)) {
|
||
map.put("TimeStamp", timeStamp);
|
||
}
|
||
String seq = dto.getSeq();
|
||
if (StringUtils.isNotBlank(seq)) {
|
||
map.put("Seq", seq);
|
||
}
|
||
// 计算sign
|
||
String sign = GBSignUtils.sign(map, signSecret);
|
||
logger.info("sign:{}, dto.getSig():{}", sign, dto.getSig());
|
||
return StringUtils.equals(dto.getSig(), sign);
|
||
}
|
||
|
||
}
|