mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
秘钥管理改造,服务端返回sign
This commit is contained in:
@@ -17,6 +17,12 @@ public interface Isv {
|
|||||||
*/
|
*/
|
||||||
String getSecretInfo();
|
String getSecretInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台的私钥
|
||||||
|
* @return 返回私钥
|
||||||
|
*/
|
||||||
|
String getPrivateKeyPlatform();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 0启用,1禁用
|
* 0启用,1禁用
|
||||||
* @return 返回状态
|
* @return 返回状态
|
||||||
|
@@ -2,9 +2,6 @@ package com.gitee.sop.gatewaycommon.bean;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
@@ -13,6 +10,8 @@ import java.util.Date;
|
|||||||
@Setter
|
@Setter
|
||||||
public class IsvDefinition implements Isv {
|
public class IsvDefinition implements Isv {
|
||||||
|
|
||||||
|
public static final int SIGN_TYPE_RSA2 = 1;
|
||||||
|
|
||||||
public IsvDefinition() {
|
public IsvDefinition() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,35 +20,38 @@ public class IsvDefinition implements Isv {
|
|||||||
this.secret = secret;
|
this.secret = secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String appKey;
|
private String appKey;
|
||||||
|
|
||||||
/** 秘钥,如果是支付宝开放平台,对应的pubKey */
|
/** 秘钥,签名方式为MD5时有用 */
|
||||||
private String secret;
|
private String secret;
|
||||||
|
|
||||||
private String pubKey;
|
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||||
|
private String publicKeyIsv;
|
||||||
|
|
||||||
|
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||||
|
private String privateKeyPlatform;
|
||||||
|
|
||||||
/** 0启用,1禁用 */
|
/** 0启用,1禁用 */
|
||||||
private Byte status;
|
private Byte status;
|
||||||
|
|
||||||
private Date gmtCreate;
|
/** 签名类型:1:RSA2,2:MD5 */
|
||||||
|
private Byte signType = 1;
|
||||||
private Date gmtModified;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSecretInfo() {
|
public String getSecretInfo() {
|
||||||
return StringUtils.isBlank(pubKey) ? secret : pubKey;
|
return signType == SIGN_TYPE_RSA2 ? publicKeyIsv : secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "IsvDefinition{" +
|
return "IsvDefinition{" +
|
||||||
"id=" + id +
|
"appKey='" + appKey + '\'' +
|
||||||
", appKey='" + appKey + '\'' +
|
", secret='" + secret + '\'' +
|
||||||
|
", publicKeyIsv='" + publicKeyIsv + '\'' +
|
||||||
|
", privateKeyPlatform='" + privateKeyPlatform + '\'' +
|
||||||
", status=" + status +
|
", status=" + status +
|
||||||
", gmtCreate=" + gmtCreate +
|
", signType=" + signType +
|
||||||
", gmtModified=" + gmtModified +
|
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@ public class SopConstants {
|
|||||||
private SopConstants() {}
|
private SopConstants() {}
|
||||||
|
|
||||||
public static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;
|
public static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;
|
||||||
|
public static final String UTF8 = "UTF-8";
|
||||||
public static final String FORMAT_JSON = "json";
|
public static final String FORMAT_JSON = "json";
|
||||||
public static final String DEFAULT_SIGN_METHOD = "md5";
|
public static final String DEFAULT_SIGN_METHOD = "md5";
|
||||||
public static final String EMPTY_JSON = "{}";
|
public static final String EMPTY_JSON = "{}";
|
||||||
|
@@ -3,7 +3,6 @@ package com.gitee.sop.gatewaycommon.easyopen;
|
|||||||
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
|
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
|
||||||
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||||
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
||||||
import com.gitee.sop.gatewaycommon.secret.SecretContext;
|
|
||||||
import com.gitee.sop.gatewaycommon.zuul.configuration.BaseZuulConfiguration;
|
import com.gitee.sop.gatewaycommon.zuul.configuration.BaseZuulConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,10 +10,6 @@ import com.gitee.sop.gatewaycommon.zuul.configuration.BaseZuulConfiguration;
|
|||||||
*/
|
*/
|
||||||
public class EasyopenZuulConfiguration extends BaseZuulConfiguration {
|
public class EasyopenZuulConfiguration extends BaseZuulConfiguration {
|
||||||
|
|
||||||
static {
|
|
||||||
SecretContext.setSecretGetter((isvDefinition)-> isvDefinition.getSecret());
|
|
||||||
}
|
|
||||||
|
|
||||||
public EasyopenZuulConfiguration() {
|
public EasyopenZuulConfiguration() {
|
||||||
ApiConfig apiConfig = ApiContext.getApiConfig();
|
ApiConfig apiConfig = ApiContext.getApiConfig();
|
||||||
if (compatibilityModel()) {
|
if (compatibilityModel()) {
|
||||||
|
@@ -7,17 +7,23 @@ import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
|||||||
import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition;
|
import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition;
|
||||||
import com.gitee.sop.gatewaycommon.bean.BaseServiceRouteInfo;
|
import com.gitee.sop.gatewaycommon.bean.BaseServiceRouteInfo;
|
||||||
import com.gitee.sop.gatewaycommon.bean.ErrorDefinition;
|
import com.gitee.sop.gatewaycommon.bean.ErrorDefinition;
|
||||||
|
import com.gitee.sop.gatewaycommon.bean.Isv;
|
||||||
import com.gitee.sop.gatewaycommon.bean.SopConstants;
|
import com.gitee.sop.gatewaycommon.bean.SopConstants;
|
||||||
import com.gitee.sop.gatewaycommon.bean.TargetRoute;
|
import com.gitee.sop.gatewaycommon.bean.TargetRoute;
|
||||||
import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext;
|
import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext;
|
||||||
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
||||||
import com.gitee.sop.gatewaycommon.message.ErrorMeta;
|
import com.gitee.sop.gatewaycommon.message.ErrorMeta;
|
||||||
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
||||||
|
import com.gitee.sop.gatewaycommon.secret.IsvManager;
|
||||||
|
import com.gitee.sop.gatewaycommon.validate.alipay.AlipayConstants;
|
||||||
|
import com.gitee.sop.gatewaycommon.validate.alipay.AlipaySignature;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang.BooleanUtils;
|
import org.apache.commons.lang.BooleanUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -26,6 +32,7 @@ import java.util.Optional;
|
|||||||
/**
|
/**
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R> {
|
public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R> {
|
||||||
private static final ErrorMeta SUCCESS_META = ErrorEnum.SUCCESS.getErrorMeta();
|
private static final ErrorMeta SUCCESS_META = ErrorEnum.SUCCESS.getErrorMeta();
|
||||||
private static final ErrorMeta ISP_UNKNOW_ERROR_META = ErrorEnum.ISP_UNKNOW_ERROR.getErrorMeta();
|
private static final ErrorMeta ISP_UNKNOW_ERROR_META = ErrorEnum.ISP_UNKNOW_ERROR.getErrorMeta();
|
||||||
@@ -36,6 +43,7 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
|||||||
public static final String ARRAY_START = "[";
|
public static final String ARRAY_START = "[";
|
||||||
public static final String ARRAY_END = "]";
|
public static final String ARRAY_END = "]";
|
||||||
public static final String ROOT_JSON = "{'items':%s}".replace("'", "\"");
|
public static final String ROOT_JSON = "{'items':%s}".replace("'", "\"");
|
||||||
|
public static final String ERROR_METHOD = "error";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,33 +78,33 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
|||||||
}
|
}
|
||||||
serviceResult = wrapResult(serviceResult);
|
serviceResult = wrapResult(serviceResult);
|
||||||
int responseStatus = this.getResponseStatus(request);
|
int responseStatus = this.getResponseStatus(request);
|
||||||
JSONObject jsonObjectService;
|
JSONObject responseData;
|
||||||
if (responseStatus == HttpStatus.OK.value()) {
|
if (responseStatus == HttpStatus.OK.value()) {
|
||||||
// 200正常返回
|
// 200正常返回
|
||||||
jsonObjectService = JSON.parseObject(serviceResult);
|
responseData = JSON.parseObject(serviceResult);
|
||||||
jsonObjectService.put(GATEWAY_CODE_NAME, SUCCESS_META.getCode());
|
responseData.put(GATEWAY_CODE_NAME, SUCCESS_META.getCode());
|
||||||
jsonObjectService.put(GATEWAY_MSG_NAME, SUCCESS_META.getError().getMsg());
|
responseData.put(GATEWAY_MSG_NAME, SUCCESS_META.getError().getMsg());
|
||||||
} else if (responseStatus == SopConstants.BIZ_ERROR_STATUS) {
|
} else if (responseStatus == SopConstants.BIZ_ERROR_STATUS) {
|
||||||
// 如果是业务出错
|
// 如果是业务出错
|
||||||
this.storeError(request, ErrorType.BIZ);
|
this.storeError(request, ErrorType.BIZ);
|
||||||
jsonObjectService = JSON.parseObject(serviceResult);
|
responseData = JSON.parseObject(serviceResult);
|
||||||
jsonObjectService.put(GATEWAY_CODE_NAME, ISP_BIZ_ERROR.getCode());
|
responseData.put(GATEWAY_CODE_NAME, ISP_BIZ_ERROR.getCode());
|
||||||
jsonObjectService.put(GATEWAY_MSG_NAME, ISP_BIZ_ERROR.getError().getMsg());
|
responseData.put(GATEWAY_MSG_NAME, ISP_BIZ_ERROR.getError().getMsg());
|
||||||
} else {
|
} else {
|
||||||
this.storeError(request, ErrorType.UNKNOWN);
|
this.storeError(request, ErrorType.UNKNOWN);
|
||||||
// 微服务端有可能返回500错误
|
// 微服务端有可能返回500错误
|
||||||
// {"path":"/book/getBook3","error":"Internal Server Error","message":"id不能为空","timestamp":"2019-02-13T07:41:00.495+0000","status":500}
|
// {"path":"/book/getBook3","error":"Internal Server Error","message":"id不能为空","timestamp":"2019-02-13T07:41:00.495+0000","status":500}
|
||||||
jsonObjectService = new JSONObject();
|
responseData = new JSONObject();
|
||||||
jsonObjectService.put(GATEWAY_CODE_NAME, ISP_UNKNOW_ERROR_META.getCode());
|
responseData.put(GATEWAY_CODE_NAME, ISP_UNKNOW_ERROR_META.getCode());
|
||||||
jsonObjectService.put(GATEWAY_MSG_NAME, ISP_UNKNOW_ERROR_META.getError().getMsg());
|
responseData.put(GATEWAY_MSG_NAME, ISP_UNKNOW_ERROR_META.getError().getMsg());
|
||||||
}
|
}
|
||||||
return this.merge(request, jsonObjectService);
|
return this.merge(request, responseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存错误信息
|
* 保存错误信息
|
||||||
*
|
*
|
||||||
* @param request
|
* @param request request
|
||||||
*/
|
*/
|
||||||
protected void storeError(T request, ErrorType errorType) {
|
protected void storeError(T request, ErrorType errorType) {
|
||||||
ApiInfo apiInfo = this.getApiInfo(request);
|
ApiInfo apiInfo = this.getApiInfo(request);
|
||||||
@@ -116,7 +124,7 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
|||||||
/**
|
/**
|
||||||
* 该路由是否合并结果
|
* 该路由是否合并结果
|
||||||
*
|
*
|
||||||
* @param request
|
* @param request request
|
||||||
* @return true:需要合并
|
* @return true:需要合并
|
||||||
*/
|
*/
|
||||||
protected boolean isMergeResult(T request) {
|
protected boolean isMergeResult(T request) {
|
||||||
@@ -137,13 +145,8 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
|||||||
|
|
||||||
protected ApiInfo getApiInfo(T request) {
|
protected ApiInfo getApiInfo(T request) {
|
||||||
Map<String, Object> params = this.getApiParam(request);
|
Map<String, Object> params = this.getApiParam(request);
|
||||||
String name = Optional.ofNullable(params)
|
String name = this.getParamValue(params, ParamNames.API_NAME, "method.unknown");
|
||||||
.map(map -> (String) map.get(ParamNames.API_NAME))
|
String version = this.getParamValue(params, ParamNames.VERSION_NAME, "version.unknown");
|
||||||
.orElse("method.unknown");
|
|
||||||
|
|
||||||
String version = Optional.ofNullable(params)
|
|
||||||
.map(map -> (String) map.get(ParamNames.VERSION_NAME))
|
|
||||||
.orElse("version.unknown");
|
|
||||||
|
|
||||||
TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(name + version);
|
TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(name + version);
|
||||||
|
|
||||||
@@ -178,46 +181,66 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
|||||||
return serviceResult;
|
return serviceResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String merge(T exchange, JSONObject jsonObjectService) {
|
public String merge(T exchange, JSONObject responseData) {
|
||||||
JSONObject ret = new JSONObject();
|
JSONObject finalData = new JSONObject();
|
||||||
String name = "error";
|
|
||||||
Map<String, Object> params = this.getApiParam(exchange);
|
Map<String, Object> params = this.getApiParam(exchange);
|
||||||
if (params != null) {
|
String name = this.getParamValue(params, ParamNames.API_NAME, ERROR_METHOD);
|
||||||
Object method = params.get(ParamNames.API_NAME);
|
|
||||||
if (method != null) {
|
|
||||||
name = String.valueOf(method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ApiConfig apiConfig = ApiConfig.getInstance();
|
ApiConfig apiConfig = ApiConfig.getInstance();
|
||||||
// 点换成下划线
|
// 点换成下划线
|
||||||
DataNameBuilder dataNameBuilder = apiConfig.getDataNameBuilder();
|
DataNameBuilder dataNameBuilder = apiConfig.getDataNameBuilder();
|
||||||
String method = dataNameBuilder.build(name);
|
// alipay_goods_get_response
|
||||||
ret.put(method, jsonObjectService);
|
String responseDataNodeName = dataNameBuilder.build(name);
|
||||||
this.appendReturnSign(apiConfig, params, ret);
|
finalData.put(responseDataNodeName, responseData);
|
||||||
ResultAppender resultAppender = apiConfig.getResultAppender();
|
ResultAppender resultAppender = apiConfig.getResultAppender();
|
||||||
|
// 追加额外的结果
|
||||||
if (resultAppender != null) {
|
if (resultAppender != null) {
|
||||||
resultAppender.append(ret, params, exchange);
|
resultAppender.append(finalData, params, exchange);
|
||||||
}
|
}
|
||||||
return ret.toJSONString();
|
// 添加服务端sign
|
||||||
|
if (apiConfig.isShowReturnSign() && !CollectionUtils.isEmpty(params)) {
|
||||||
|
// 添加try...catch,生成sign出错不影响结果正常返回
|
||||||
|
try {
|
||||||
|
String sign = this.createResponseSign(apiConfig, params, responseData.toJSONString());
|
||||||
|
if (StringUtils.hasLength(sign)) {
|
||||||
|
finalData.put(ParamNames.SIGN_NAME, sign);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("生成平台签名失败, params: {}, serviceResult:{}", JSON.toJSONString(params), responseData, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finalData.toJSONString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void appendReturnSign(ApiConfig apiConfig, Map<String, ?> params, JSONObject ret) {
|
protected String getParamValue(Map<String, Object> apiParam, String key, String defaultValue) {
|
||||||
if (apiConfig.isShowReturnSign() && params != null) {
|
return CollectionUtils.isEmpty(apiParam) ? defaultValue : (String) apiParam.getOrDefault(key, defaultValue);
|
||||||
Object appKey = params.get(ParamNames.APP_KEY_NAME);
|
|
||||||
String sign = this.createReturnSign(String.valueOf(appKey));
|
|
||||||
ret.put(ParamNames.SIGN_NAME, sign);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 这里需要使用平台的私钥生成一个sign,需要配置两套公私钥。目前暂未实现
|
* 这里需要使用平台的私钥生成一个sign,需要配置两套公私钥。
|
||||||
*
|
*
|
||||||
* @param appKey
|
* @param apiConfig 配置
|
||||||
* @return
|
* @param params 请求参数
|
||||||
|
* @param serviceResult 业务返回结果
|
||||||
|
* @return 返回平台生成的签名
|
||||||
*/
|
*/
|
||||||
protected String createReturnSign(String appKey) {
|
protected String createResponseSign(ApiConfig apiConfig, Map<String, Object> params, String serviceResult) {
|
||||||
// TODO: 返回sign
|
IsvManager isvManager = apiConfig.getIsvManager();
|
||||||
return null;
|
// 根据appId获取秘钥
|
||||||
|
String appKey = this.getParamValue(params, ParamNames.APP_KEY_NAME, "");
|
||||||
|
if (StringUtils.isEmpty(appKey)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Isv isvInfo = isvManager.getIsv(appKey);
|
||||||
|
String privateKeyPlatform = isvInfo.getPrivateKeyPlatform();
|
||||||
|
if (StringUtils.isEmpty(privateKeyPlatform)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String charset = Optional.ofNullable(params.get(ParamNames.CHARSET_NAME))
|
||||||
|
.map(String::valueOf)
|
||||||
|
.orElse(SopConstants.UTF8);
|
||||||
|
String signType = getParamValue(params, ParamNames.SIGN_TYPE_NAME, AlipayConstants.SIGN_TYPE_RSA2);
|
||||||
|
return AlipaySignature.rsaSign(serviceResult, privateKeyPlatform, charset, signType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
@@ -1,20 +0,0 @@
|
|||||||
package com.gitee.sop.gatewaycommon.secret;
|
|
||||||
|
|
||||||
import com.gitee.sop.gatewaycommon.bean.IsvDefinition;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
public class SecretContext {
|
|
||||||
private static volatile Function<IsvDefinition, String> secretGetter = (isv) -> isv.getPubKey();
|
|
||||||
|
|
||||||
public static Function<IsvDefinition, String> getSecretGetter() {
|
|
||||||
return secretGetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setSecretGetter(Function<IsvDefinition, String> secretGetter) {
|
|
||||||
SecretContext.secretGetter = secretGetter;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -2,8 +2,11 @@ package com.gitee.sop.gatewaycommon.validate;
|
|||||||
|
|
||||||
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
|
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
|
||||||
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||||
|
import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition;
|
||||||
import com.gitee.sop.gatewaycommon.bean.Isv;
|
import com.gitee.sop.gatewaycommon.bean.Isv;
|
||||||
import com.gitee.sop.gatewaycommon.bean.RouteConfig;
|
import com.gitee.sop.gatewaycommon.bean.RouteConfig;
|
||||||
|
import com.gitee.sop.gatewaycommon.bean.TargetRoute;
|
||||||
|
import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.RouteConfigManager;
|
import com.gitee.sop.gatewaycommon.manager.RouteConfigManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext;
|
import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext;
|
||||||
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
||||||
@@ -12,6 +15,7 @@ import com.gitee.sop.gatewaycommon.param.ParamNames;
|
|||||||
import com.gitee.sop.gatewaycommon.param.UploadContext;
|
import com.gitee.sop.gatewaycommon.param.UploadContext;
|
||||||
import com.gitee.sop.gatewaycommon.secret.IsvManager;
|
import com.gitee.sop.gatewaycommon.secret.IsvManager;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
@@ -57,6 +61,7 @@ public class ApiValidator implements Validator {
|
|||||||
checkTimeout(param);
|
checkTimeout(param);
|
||||||
checkFormat(param);
|
checkFormat(param);
|
||||||
checkUploadFile(param);
|
checkUploadFile(param);
|
||||||
|
checkPermission(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,9 +161,8 @@ public class ApiValidator implements Validator {
|
|||||||
throw ErrorEnum.ISV_MISSING_SIGNATURE_CONFIG.getErrorMeta().getException();
|
throw ErrorEnum.ISV_MISSING_SIGNATURE_CONFIG.getErrorMeta().getException();
|
||||||
}
|
}
|
||||||
Signer signer = apiConfig.getSigner();
|
Signer signer = apiConfig.getSigner();
|
||||||
boolean isRightSign = signer.checkSign(param, secret);
|
|
||||||
// 错误的sign
|
// 错误的sign
|
||||||
if (!isRightSign) {
|
if (!signer.checkSign(param, secret)) {
|
||||||
throw ErrorEnum.ISV_INVALID_SIGNATURE.getErrorMeta().getException(param.fetchNameVersion());
|
throw ErrorEnum.ISV_INVALID_SIGNATURE.getErrorMeta().getException(param.fetchNameVersion());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -177,4 +181,23 @@ public class ApiValidator implements Validator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验访问权限
|
||||||
|
* @param apiParam
|
||||||
|
*/
|
||||||
|
protected void checkPermission(ApiParam apiParam) {
|
||||||
|
String routeId = apiParam.fetchNameVersion();
|
||||||
|
TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId);
|
||||||
|
BaseRouteDefinition routeDefinition = targetRoute.getRouteDefinition();
|
||||||
|
boolean needCheckPermission = BooleanUtils.toBoolean(routeDefinition.getPermission());
|
||||||
|
if (needCheckPermission) {
|
||||||
|
IsvRoutePermissionManager isvRoutePermissionManager = ApiConfig.getInstance().getIsvRoutePermissionManager();
|
||||||
|
String appKey = apiParam.fetchAppKey();
|
||||||
|
boolean hasPermission = isvRoutePermissionManager.hasPermission(appKey, routeId);
|
||||||
|
if (!hasPermission) {
|
||||||
|
throw ErrorEnum.ISV_ROUTE_NO_PERMISSIONS.getErrorMeta().getException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -88,16 +88,16 @@ public class AlipaySignature {
|
|||||||
* sha256WithRsa 加签
|
* sha256WithRsa 加签
|
||||||
*
|
*
|
||||||
* @param content
|
* @param content
|
||||||
* @param publicKey
|
* @param privateKey
|
||||||
* @param charset
|
* @param charset
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String rsa256Sign(String content, String publicKey,
|
public static String rsa256Sign(String content, String privateKey,
|
||||||
String charset) {
|
String charset) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PrivateKey priKey = getPrivateKeyFromPKCS8(AlipayConstants.SIGN_TYPE_RSA,
|
PrivateKey priKey = getPrivateKeyFromPKCS8(AlipayConstants.SIGN_TYPE_RSA,
|
||||||
new ByteArrayInputStream(publicKey.getBytes()));
|
new ByteArrayInputStream(privateKey.getBytes()));
|
||||||
|
|
||||||
java.security.Signature signature = java.security.Signature
|
java.security.Signature signature = java.security.Signature
|
||||||
.getInstance(AlipayConstants.SIGN_SHA256RSA_ALGORITHMS);
|
.getInstance(AlipayConstants.SIGN_SHA256RSA_ALGORITHMS);
|
||||||
|
@@ -7,7 +7,6 @@ import com.gitee.sop.gatewaycommon.zuul.filter.ErrorFilter;
|
|||||||
import com.gitee.sop.gatewaycommon.zuul.filter.FormBodyWrapperFilterExt;
|
import com.gitee.sop.gatewaycommon.zuul.filter.FormBodyWrapperFilterExt;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.filter.PostResultFilter;
|
import com.gitee.sop.gatewaycommon.zuul.filter.PostResultFilter;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.filter.PreLimitFilter;
|
import com.gitee.sop.gatewaycommon.zuul.filter.PreLimitFilter;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.filter.PreRoutePermissionFilter;
|
|
||||||
import com.gitee.sop.gatewaycommon.zuul.filter.PreValidateFilter;
|
import com.gitee.sop.gatewaycommon.zuul.filter.PreValidateFilter;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.filter.Servlet30WrapperFilterExt;
|
import com.gitee.sop.gatewaycommon.zuul.filter.Servlet30WrapperFilterExt;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.route.SopRouteLocator;
|
import com.gitee.sop.gatewaycommon.zuul.route.SopRouteLocator;
|
||||||
@@ -96,14 +95,6 @@ public class BaseZuulConfiguration extends AbstractConfiguration {
|
|||||||
return new PreLimitFilter();
|
return new PreLimitFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 权限校验
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
PreRoutePermissionFilter preRoutePermissionFilter() {
|
|
||||||
return new PreRoutePermissionFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误处理扩展
|
* 错误处理扩展
|
||||||
*/
|
*/
|
||||||
|
@@ -15,7 +15,9 @@ import org.apache.commons.lang3.BooleanUtils;
|
|||||||
/**
|
/**
|
||||||
* 路由权限校验,有些接口需要配置权限才能访问。
|
* 路由权限校验,有些接口需要配置权限才能访问。
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
|
* @deprecated 已经整合到ApiValidator中,见ApiValidator.checkPermission()
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class PreRoutePermissionFilter extends BaseZuulFilter {
|
public class PreRoutePermissionFilter extends BaseZuulFilter {
|
||||||
@Override
|
@Override
|
||||||
protected FilterType getFilterType() {
|
protected FilterType getFilterType() {
|
||||||
|
Reference in New Issue
Block a user