mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
返回sign处理
This commit is contained in:
@@ -11,6 +11,7 @@ using SDKCSharp.Request;
|
|||||||
using SDKCSharp.Response;
|
using SDKCSharp.Response;
|
||||||
using SDKCSharp.Utility;
|
using SDKCSharp.Utility;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace SDKCSharp.Client
|
namespace SDKCSharp.Client
|
||||||
{
|
{
|
||||||
@@ -21,7 +22,6 @@ namespace SDKCSharp.Client
|
|||||||
{
|
{
|
||||||
|
|
||||||
private static OpenConfig DEFAULT_CONFIG = new OpenConfig();
|
private static OpenConfig DEFAULT_CONFIG = new OpenConfig();
|
||||||
private const string ERROR_RESPONSE_KEY = "error_response";
|
|
||||||
|
|
||||||
private Dictionary<string, string> header = new Dictionary<string, string>();
|
private Dictionary<string, string> header = new Dictionary<string, string>();
|
||||||
|
|
||||||
@@ -29,22 +29,37 @@ namespace SDKCSharp.Client
|
|||||||
private string url;
|
private string url;
|
||||||
private string appId;
|
private string appId;
|
||||||
private string privateKey;
|
private string privateKey;
|
||||||
|
private string publicKeyPlatform;
|
||||||
|
|
||||||
private OpenConfig openConfig;
|
private OpenConfig openConfig;
|
||||||
private OpenRequest openRequest;
|
private OpenRequest openRequest;
|
||||||
private DataNameBuilder dataNameBuilder;
|
private DataNameBuilder dataNameBuilder;
|
||||||
|
|
||||||
|
|
||||||
public OpenClient(string url, string appId, string privateKey) : this(url, appId, privateKey,false, DEFAULT_CONFIG)
|
public OpenClient(string url, string appId, string privateKey)
|
||||||
|
: this(url, appId, privateKey,false, DEFAULT_CONFIG)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile) : this(url, appId, privateKey, priKeyFromFile, DEFAULT_CONFIG)
|
public OpenClient(string url, string appId, string privateKey, string publicKeyPlatform)
|
||||||
|
: this(url, appId, privateKey)
|
||||||
|
{
|
||||||
|
this.publicKeyPlatform = publicKeyPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile)
|
||||||
|
: this(url, appId, privateKey, priKeyFromFile, DEFAULT_CONFIG)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile, string publicKeyPlatform)
|
||||||
|
: this(url, appId, privateKey, priKeyFromFile)
|
||||||
|
{
|
||||||
|
this.publicKeyPlatform = publicKeyPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
public OpenClient(string url, string appId, string privateKey,bool priKeyFromFile, OpenConfig openConfig)
|
public OpenClient(string url, string appId, string privateKey,bool priKeyFromFile, OpenConfig openConfig)
|
||||||
{
|
{
|
||||||
this.url = url;
|
this.url = url;
|
||||||
@@ -60,6 +75,12 @@ namespace SDKCSharp.Client
|
|||||||
this.dataNameBuilder = openConfig.DataNameBuilder;
|
this.dataNameBuilder = openConfig.DataNameBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile, string publicKeyPlatform, OpenConfig openConfig)
|
||||||
|
: this(url, appId, privateKey, priKeyFromFile, openConfig)
|
||||||
|
{
|
||||||
|
this.publicKeyPlatform = publicKeyPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载秘钥文件
|
/// 加载秘钥文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -106,7 +127,7 @@ namespace SDKCSharp.Client
|
|||||||
form[this.openConfig.AccessTokenName] = accessToken;
|
form[this.openConfig.AccessTokenName] = accessToken;
|
||||||
}
|
}
|
||||||
form[this.openConfig.AppKeyName] = this.appId;
|
form[this.openConfig.AppKeyName] = this.appId;
|
||||||
string sign = SignUtil.CreateSign(form, privateKey, request.Charset, request.SignType);
|
string sign = SignUtil.CreateSign(form, privateKey, openConfig.Charset, openConfig.SignType);
|
||||||
form[this.openConfig.SignName] = sign;
|
form[this.openConfig.SignName] = sign;
|
||||||
|
|
||||||
string resp = this.DoExecute(url, requestForm, header);
|
string resp = this.DoExecute(url, requestForm, header);
|
||||||
@@ -133,22 +154,84 @@ namespace SDKCSharp.Client
|
|||||||
/// <param name="resp">服务器响应内容</param>
|
/// <param name="resp">服务器响应内容</param>
|
||||||
/// <param name="request">请求Request</param>
|
/// <param name="request">请求Request</param>
|
||||||
/// <returns>返回Response</returns>
|
/// <returns>返回Response</returns>
|
||||||
protected virtual T ParseResponse<T>(string resp, BaseRequest<T> request) where T: BaseResponse {
|
protected virtual T ParseResponse<T>(string resp, BaseRequest<T> request) where T: BaseResponse
|
||||||
|
{
|
||||||
string method = request.Method;
|
string method = request.Method;
|
||||||
string dataName = this.dataNameBuilder.Build(method);
|
string rootNodeName = this.dataNameBuilder.Build(method);
|
||||||
Dictionary<string, object> jsonObject = JsonUtil.ParseToDictionary(resp);
|
string errorRootNode = openConfig.ErrorResponseName;
|
||||||
bool errorResponse = jsonObject.ContainsKey(ERROR_RESPONSE_KEY);
|
Dictionary<string, object> responseData = JsonUtil.ParseToDictionary(resp);
|
||||||
|
bool errorResponse = responseData.ContainsKey(errorRootNode);
|
||||||
if (errorResponse)
|
if (errorResponse)
|
||||||
{
|
{
|
||||||
dataName = ERROR_RESPONSE_KEY;
|
rootNodeName = errorRootNode;
|
||||||
|
}
|
||||||
|
object data = responseData[rootNodeName];
|
||||||
|
responseData.TryGetValue(openConfig.SignName, out object sign);
|
||||||
|
if (sign != null && !string.IsNullOrEmpty(publicKeyPlatform))
|
||||||
|
{
|
||||||
|
string signContent = BuildBizJson(rootNodeName, resp);
|
||||||
|
if (!CheckResponseSign(signContent, sign.ToString(), publicKeyPlatform))
|
||||||
|
{
|
||||||
|
ErrorResponse checkSignErrorResponse = SopSdkErrors.CHECK_RESPONSE_SIGN_ERROR;
|
||||||
|
data = JsonUtil.ToJSONString(checkSignErrorResponse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
object data = jsonObject[dataName];
|
|
||||||
string jsonData = data == null ? "{}" : data.ToString();
|
string jsonData = data == null ? "{}" : data.ToString();
|
||||||
T t = JsonUtil.ParseObject<T>(jsonData);
|
T t = JsonUtil.ParseObject<T>(jsonData);
|
||||||
t.Body = jsonData;
|
t.Body = jsonData;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证服务端返回的sign
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c>, if response sign was checked, <c>false</c> otherwise.</returns>
|
||||||
|
/// <param name="signContent">Response data.</param>
|
||||||
|
/// <param name="sign">sign data.</param>
|
||||||
|
/// <param name="publicKeyPlatform">Public key platform.</param>
|
||||||
|
protected virtual bool CheckResponseSign(string signContent, string sign, string publicKeyPlatform)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Encoding charset = openConfig.Charset;
|
||||||
|
SignType signType = openConfig.SignType;
|
||||||
|
return SignUtil.RsaCheck(signContent, sign, publicKeyPlatform, charset, signType);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string BuildBizJson(string rootNodeName, string body)
|
||||||
|
{
|
||||||
|
int indexOfRootNode = body.IndexOf(rootNodeName);
|
||||||
|
if (indexOfRootNode < 0)
|
||||||
|
{
|
||||||
|
rootNodeName = openConfig.ErrorResponseName;
|
||||||
|
indexOfRootNode = body.IndexOf(rootNodeName);
|
||||||
|
}
|
||||||
|
string result = null;
|
||||||
|
if (indexOfRootNode > 0)
|
||||||
|
{
|
||||||
|
result = BuildJsonNodeData(body, rootNodeName, indexOfRootNode);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string BuildJsonNodeData(string body, string rootNode, int indexOfRootNode)
|
||||||
|
{
|
||||||
|
int signDataStartIndex = indexOfRootNode + rootNode.Length + 2;
|
||||||
|
int indexOfSign = body.IndexOf("\"" + openConfig.SignName + "\"");
|
||||||
|
if (indexOfSign < 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int signDataEndIndex = indexOfSign - 1;
|
||||||
|
int length = signDataEndIndex - signDataStartIndex;
|
||||||
|
|
||||||
|
return body.Substring(signDataStartIndex, length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,9 +13,6 @@ namespace SDKCSharp.Client
|
|||||||
{
|
{
|
||||||
public class OpenRequest
|
public class OpenRequest
|
||||||
{
|
{
|
||||||
|
|
||||||
private const string HTTP_ERROR_CODE = "-400";
|
|
||||||
|
|
||||||
private OpenConfig openConfig;
|
private OpenConfig openConfig;
|
||||||
private OpenHttp openHttp;
|
private OpenHttp openHttp;
|
||||||
|
|
||||||
@@ -77,17 +74,10 @@ namespace SDKCSharp.Client
|
|||||||
|
|
||||||
protected string CauseException(Exception e)
|
protected string CauseException(Exception e)
|
||||||
{
|
{
|
||||||
ErrorResponse result = new ErrorResponse();
|
ErrorResponse result = SopSdkErrors.HTTP_ERROR;
|
||||||
result.SubCode = HTTP_ERROR_CODE;
|
|
||||||
result.SubMsg = e.Message;
|
|
||||||
result.Code = HTTP_ERROR_CODE;
|
|
||||||
result.Msg = e.Message;
|
|
||||||
return JsonUtil.ToJSONString(result);
|
return JsonUtil.ToJSONString(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ErrorResponse : BaseResponse
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ namespace SDKCSharp.Common
|
|||||||
|
|
||||||
private const char DOT = '.';
|
private const char DOT = '.';
|
||||||
private const char UNDERLINE = '_';
|
private const char UNDERLINE = '_';
|
||||||
private const string DATA_SUFFIX = "_response";
|
private const string DATA_SUFFIX = SopSdkConstants.DATA_SUFFIX;
|
||||||
|
|
||||||
public string Build(string method)
|
public string Build(string method)
|
||||||
{
|
{
|
||||||
|
8
sop-sdk/sdk-csharp/SDKCSharp/Common/ErrorResponse.cs
Normal file
8
sop-sdk/sdk-csharp/SDKCSharp/Common/ErrorResponse.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
namespace SDKCSharp.Common
|
||||||
|
{
|
||||||
|
public class ErrorResponse: Response.BaseResponse
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -5,192 +5,132 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using SDKCSharp;
|
using SDKCSharp;
|
||||||
|
using SDKCSharp.Utility;
|
||||||
|
|
||||||
namespace SDKCSharp.Common
|
namespace SDKCSharp.Common
|
||||||
{
|
{
|
||||||
public class OpenConfig
|
public class OpenConfig
|
||||||
{
|
{
|
||||||
|
public static DataNameBuilder DATA_NAME_BUILDER = new DefaultDataNameBuilder();
|
||||||
private String successCode = SdkConfig.SUCCESS_CODE;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回码成功值
|
/// 返回码成功值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String SuccessCode
|
public string SuccessCode { get; set; } = "10000";
|
||||||
{
|
|
||||||
get { return successCode; }
|
|
||||||
set { successCode = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String defaultVersion = SdkConfig.DEFAULT_VERSION;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认版本号
|
/// 默认版本号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String DefaultVersion
|
public string DefaultVersion { get; set; } = "1.0";
|
||||||
{
|
|
||||||
get { return defaultVersion; }
|
/// <summary>
|
||||||
set { defaultVersion = value; }
|
/// 字符编码
|
||||||
}
|
/// </summary>
|
||||||
|
/// <value>The charset.</value>
|
||||||
|
public Encoding Charset { get; set; } = Encoding.UTF8;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 签名类型
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The type of the sign.</value>
|
||||||
|
public SignType SignType { get; set; } = SignType.RSA2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 格式类型
|
||||||
|
/// </summary>
|
||||||
|
public string FormatType { get; set; } = "json";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 时间戳格式
|
||||||
|
/// </summary>
|
||||||
|
public string TimestampPattern { get; set; } = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
|
||||||
private String methodName = "method";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 接口属性名
|
/// 接口属性名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String MethodName
|
public string MethodName { get; set; } = "method";
|
||||||
{
|
|
||||||
get { return methodName; }
|
|
||||||
set { methodName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String versionName = "version";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 版本号名称
|
/// 版本号名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String VersionName
|
public string VersionName { get; set; } = "version";
|
||||||
{
|
|
||||||
get { return versionName; }
|
|
||||||
set { versionName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String charsetName = "charset";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 编码名称
|
/// 编码名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The name of the charset.</value>
|
/// <value>The name of the charset.</value>
|
||||||
public string CharsetName { get => charsetName; set => charsetName = value; }
|
public string CharsetName { get; set; } = "charset";
|
||||||
|
|
||||||
private String appKeyName = "app_id";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// appKey名称
|
/// appKey名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String AppKeyName
|
public string AppKeyName { get; set; } = "app_id";
|
||||||
{
|
|
||||||
get { return appKeyName; }
|
|
||||||
set { appKeyName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String dataName = "biz_content";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// data名称
|
/// data名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String DataName
|
public string DataName { get; set; } = "biz_content";
|
||||||
{
|
|
||||||
get { return dataName; }
|
|
||||||
set { dataName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String timestampName = "timestamp";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 时间戳名称
|
/// 时间戳名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String TimestampName
|
public string TimestampName { get; set; } = "timestamp";
|
||||||
{
|
|
||||||
get { return timestampName; }
|
|
||||||
set { timestampName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String timestampPattern = "yyyy-MM-dd HH:mm:ss";
|
|
||||||
/// <summary>
|
|
||||||
/// 时间戳格式
|
|
||||||
/// </summary>
|
|
||||||
public String TimestampPattern
|
|
||||||
{
|
|
||||||
get { return timestampPattern; }
|
|
||||||
set { timestampPattern = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signName = "sign";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 签名串名称
|
/// 签名串名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public String SignName
|
public string SignName { get; set; } = "sign";
|
||||||
{
|
|
||||||
get { return signName; }
|
|
||||||
set { signName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatName = "format";
|
|
||||||
/// <summary>
|
|
||||||
/// 格式化名称
|
|
||||||
/// </summary>
|
|
||||||
public String FormatName
|
|
||||||
{
|
|
||||||
get { return formatName; }
|
|
||||||
set { formatName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatType = "json";
|
|
||||||
/// <summary>
|
|
||||||
/// 格式类型
|
|
||||||
/// </summary>
|
|
||||||
public String FormatType
|
|
||||||
{
|
|
||||||
get { return formatType; }
|
|
||||||
set { formatType = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String accessTokenName = "app_auth_token";
|
|
||||||
/// <summary> accessToken名称
|
|
||||||
/// </summary>
|
|
||||||
public String AccessTokenName
|
|
||||||
{
|
|
||||||
get { return accessTokenName; }
|
|
||||||
set { accessTokenName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String locale = "zh-CN";
|
|
||||||
/// <summary>
|
|
||||||
/// 国际化语言
|
|
||||||
/// </summary>
|
|
||||||
public String Locale
|
|
||||||
{
|
|
||||||
get { return locale; }
|
|
||||||
set { locale = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private String responseCodeName = "code";
|
|
||||||
/// <summary>
|
|
||||||
/// 响应code名称
|
|
||||||
/// </summary>
|
|
||||||
public String ResponseCodeName
|
|
||||||
{
|
|
||||||
get { return responseCodeName; }
|
|
||||||
set { responseCodeName = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private int connectTimeoutSeconds = 10;
|
|
||||||
/// <summary>
|
|
||||||
/// 请求超时时间
|
|
||||||
/// </summary>
|
|
||||||
public int ConnectTimeoutSeconds
|
|
||||||
{
|
|
||||||
get { return connectTimeoutSeconds; }
|
|
||||||
set { connectTimeoutSeconds = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private int readTimeoutSeconds = 10;
|
|
||||||
/// <summary>
|
|
||||||
/// http读取超时时间
|
|
||||||
/// </summary>
|
|
||||||
public int ReadTimeoutSeconds
|
|
||||||
{
|
|
||||||
get { return readTimeoutSeconds; }
|
|
||||||
set { readTimeoutSeconds = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private string signTypeName = "sign_type";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 签名类型名称
|
/// 签名类型名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The name of the sign type.</value>
|
/// <value>The name of the sign type.</value>
|
||||||
public string SignTypeName { get => signTypeName; set => signTypeName = value; }
|
public string SignTypeName { get; set; } = "sign_type";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 格式化名称
|
||||||
|
/// </summary>
|
||||||
|
public string FormatName { get; set; } = "format";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> accessToken名称
|
||||||
|
/// </summary>
|
||||||
|
public string AccessTokenName { get; set; } = "app_auth_token";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 国际化语言
|
||||||
|
/// </summary>
|
||||||
|
public string Locale { get; set; } = "zh-CN";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 响应code名称
|
||||||
|
/// </summary>
|
||||||
|
public string ResponseCodeName { get; set; } = "code";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误响应节点
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name of the error response.</value>
|
||||||
|
public string ErrorResponseName { get; set; } = "error_response";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求超时时间
|
||||||
|
/// </summary>
|
||||||
|
public int ConnectTimeoutSeconds { get; set; } = 10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// http读取超时时间
|
||||||
|
/// </summary>
|
||||||
|
public int ReadTimeoutSeconds { get; set; } = 10;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private DataNameBuilder dataNameBuilder = SdkConfig.dataNameBuilder;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点名称构造器
|
/// 节点名称构造器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The data name builder.</value>
|
/// <value>The data name builder.</value>
|
||||||
public DataNameBuilder DataNameBuilder { get => dataNameBuilder; set => dataNameBuilder = value; }
|
public DataNameBuilder DataNameBuilder { get; set; } = DATA_NAME_BUILDER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkConstants.cs
Normal file
8
sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkConstants.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
namespace SDKCSharp.Common
|
||||||
|
{
|
||||||
|
public static class SopSdkConstants
|
||||||
|
{
|
||||||
|
public const string DATA_SUFFIX = "_response";
|
||||||
|
}
|
||||||
|
}
|
27
sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkErrors.cs
Normal file
27
sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkErrors.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
namespace SDKCSharp.Common
|
||||||
|
{
|
||||||
|
public class SopSdkErrors
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络错误
|
||||||
|
/// </summary>
|
||||||
|
public static ErrorResponse HTTP_ERROR = BuildErrorResponse("836875001", "网络错误");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证返回sign错误
|
||||||
|
/// </summary>
|
||||||
|
public static ErrorResponse CHECK_RESPONSE_SIGN_ERROR = BuildErrorResponse("836875002", "验证服务端sign出错");
|
||||||
|
|
||||||
|
public static ErrorResponse BuildErrorResponse(string code, string msg)
|
||||||
|
{
|
||||||
|
return new ErrorResponse
|
||||||
|
{
|
||||||
|
Code = code,
|
||||||
|
SubCode = code,
|
||||||
|
SubMsg = msg,
|
||||||
|
Msg = msg
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -15,15 +15,18 @@ namespace SDKTest
|
|||||||
{
|
{
|
||||||
static string url = "http://localhost:8081/api";
|
static string url = "http://localhost:8081/api";
|
||||||
static string appId = "201904035630907729292csharp";
|
static string appId = "201904035630907729292csharp";
|
||||||
// 私钥, PKCS1 2048
|
// 开发者私钥, PKCS1 2048
|
||||||
static string privateKey = "MIIEowIBAAKCAQEA5+OvJxeSzf44NxQ/cl7Ii+BzPg2k6sRcvH4ffOtU5Dzq1/oEvg02nxIhmwOHBZmjbmuUu0aLsfglUTAwqfXftfAKZidshsgj9NNh0/kxk0avRZ1UoljWGz/FxVZA0ogbxxhohPZ9jWcD+eBQcIwF2DtHfAJqWWZrYFnCMeHD8mPzxo2kwXSvDzi0vf9I2tKiYvNG26a9FqeYtPOoi81sdS3+70HOMdxP8ejXtyfnKpKz7Dx506LCIRS5moWS3Q5eTLV3NGX/1CSJ8wpQA2DAQTjVhX5eVu7Yqz12t8W+sjWM/tHUR6cgwYYR10p7tSCeCPzkigjGxKm4cYXWtATQJQIDAQABAoIBAHFDsgrrJca+NKEan77ycwx3jnKx4WrWjOF4zVKL9AQjiSYDNgvKknJyPb3kpC/lEoHdxGERHSzJoxib7DkoIqRQYhPxj73pxj5QfYk3P7LLJNNg/LTrpXDb3nL8JV9wIflGf87qQvstZTDJEyFWE4jBs7Hr0BxovWvri8InnzkmERJ1cbGJgNHe1Y3Zo2tw0yaHxQCxLuajP+notRZhD9bEp7uKeI0w9AvlW6k8m/7y10F0BK/TlyW8rQiEC391yOiRYoMcUh4hd2Q9bMx3jngZgX8PXIvZZcup4/pvWlv1alwhB2tsnLdazP62r1MO80vLyLunzGO+7WwCjEYlVaECgYEA+lQRFmbhKaPuAuXMtY31Fbga8nedka5TjnEV7+/kX+yowE2OlNujF+ZG8UTddTxAGv56yVNi/mjRlgD74j8z0eOsgvOq9mwbCrgLhLo51H9O/wAxtb+hBKtC5l50pBr4gER6d8W6EQNTSGojnMIaLXTkAZ5Qf6Z8e2HFVdOn0X0CgYEA7SSrTokwzukt5KldNu5ukyyd+C3D1i6orbg6qD73EP9CfNMfGSBn7dDv9wMSJH01+Ty+RgTROgtjGRDbMJWnfbdt/61NePr9ar5sb6Nbsf7/I0w7cZF5dsaFYgzaOfQYquzXPbLQHkpMT64bqpv/Mwy4F2lFvaYWY5fA4pC2uckCgYEAg75Ym9ybJaoTqky8ttQ2Jy8UZ4VSVQhVC0My02sCWwWXLlXi8y7An+Rec73Ve0yxREOn5WrQT6pkmzh7V/ABWrYi5WxODpCIjtSbo0fLBa3Wqle00b0/hdCITetqIa/cFs1zUrOqICgK3bKWeXqiAkhhcwSZwwSgwOKM04Wn7ZUCgYBvhHX2mbdVJfyJ8kc+hMOE/E9RHRxiBVEXWHJlGi8PVCqNDq8qHr4g7Mdbzprig+s0yKblwHAvrpkseWvKHiZEjVTyDipHgShY4TGXEigVvUd37uppTrLi8xpYcJjS9gH/px7VCdiq1d+q/MJP6coJ1KphgATm2UrgDMYNBWaYWQKBgEHRxrmER7btUF60/YgcqPHFc8RpYQB2ZZE0kyKGDqk2Data1XYUY6vsPAU28yRLAaWr/D2H17iyLkxP80VLm6QhifxCadv90Q/Wl1DFfOJQMW6avyQ0so6G0wFq/LJxaFK4iLXQn1RJnmTp6BYiJMmK2BhFbRzw8ssMoF6ad2rr";
|
static string privateKey = "MIIEowIBAAKCAQEA5+OvJxeSzf44NxQ/cl7Ii+BzPg2k6sRcvH4ffOtU5Dzq1/oEvg02nxIhmwOHBZmjbmuUu0aLsfglUTAwqfXftfAKZidshsgj9NNh0/kxk0avRZ1UoljWGz/FxVZA0ogbxxhohPZ9jWcD+eBQcIwF2DtHfAJqWWZrYFnCMeHD8mPzxo2kwXSvDzi0vf9I2tKiYvNG26a9FqeYtPOoi81sdS3+70HOMdxP8ejXtyfnKpKz7Dx506LCIRS5moWS3Q5eTLV3NGX/1CSJ8wpQA2DAQTjVhX5eVu7Yqz12t8W+sjWM/tHUR6cgwYYR10p7tSCeCPzkigjGxKm4cYXWtATQJQIDAQABAoIBAHFDsgrrJca+NKEan77ycwx3jnKx4WrWjOF4zVKL9AQjiSYDNgvKknJyPb3kpC/lEoHdxGERHSzJoxib7DkoIqRQYhPxj73pxj5QfYk3P7LLJNNg/LTrpXDb3nL8JV9wIflGf87qQvstZTDJEyFWE4jBs7Hr0BxovWvri8InnzkmERJ1cbGJgNHe1Y3Zo2tw0yaHxQCxLuajP+notRZhD9bEp7uKeI0w9AvlW6k8m/7y10F0BK/TlyW8rQiEC391yOiRYoMcUh4hd2Q9bMx3jngZgX8PXIvZZcup4/pvWlv1alwhB2tsnLdazP62r1MO80vLyLunzGO+7WwCjEYlVaECgYEA+lQRFmbhKaPuAuXMtY31Fbga8nedka5TjnEV7+/kX+yowE2OlNujF+ZG8UTddTxAGv56yVNi/mjRlgD74j8z0eOsgvOq9mwbCrgLhLo51H9O/wAxtb+hBKtC5l50pBr4gER6d8W6EQNTSGojnMIaLXTkAZ5Qf6Z8e2HFVdOn0X0CgYEA7SSrTokwzukt5KldNu5ukyyd+C3D1i6orbg6qD73EP9CfNMfGSBn7dDv9wMSJH01+Ty+RgTROgtjGRDbMJWnfbdt/61NePr9ar5sb6Nbsf7/I0w7cZF5dsaFYgzaOfQYquzXPbLQHkpMT64bqpv/Mwy4F2lFvaYWY5fA4pC2uckCgYEAg75Ym9ybJaoTqky8ttQ2Jy8UZ4VSVQhVC0My02sCWwWXLlXi8y7An+Rec73Ve0yxREOn5WrQT6pkmzh7V/ABWrYi5WxODpCIjtSbo0fLBa3Wqle00b0/hdCITetqIa/cFs1zUrOqICgK3bKWeXqiAkhhcwSZwwSgwOKM04Wn7ZUCgYBvhHX2mbdVJfyJ8kc+hMOE/E9RHRxiBVEXWHJlGi8PVCqNDq8qHr4g7Mdbzprig+s0yKblwHAvrpkseWvKHiZEjVTyDipHgShY4TGXEigVvUd37uppTrLi8xpYcJjS9gH/px7VCdiq1d+q/MJP6coJ1KphgATm2UrgDMYNBWaYWQKBgEHRxrmER7btUF60/YgcqPHFc8RpYQB2ZZE0kyKGDqk2Data1XYUY6vsPAU28yRLAaWr/D2H17iyLkxP80VLm6QhifxCadv90Q/Wl1DFfOJQMW6avyQ0so6G0wFq/LJxaFK4iLXQn1RJnmTp6BYiJMmK2BhFbRzw8ssMoF6ad2rr";
|
||||||
|
// 开放平台给的公钥
|
||||||
|
// 前往SOP-ADMIN,ISV管理--秘钥管理,选择PKCS1,生成平台提供的公私钥,然后把【平台公钥】放到这里
|
||||||
|
static string publicKeyPlatform = "";
|
||||||
|
|
||||||
// 从文件中加载
|
// 从文件中加载
|
||||||
//static string filePath = "/Users/thc/logs/priKey.txt";
|
//static string filePath = "/Users/thc/logs/priKey.txt";
|
||||||
//static OpenClient client = new OpenClient(url, appId, filePath, true);
|
//static OpenClient client = new OpenClient(url, appId, filePath, true);
|
||||||
|
|
||||||
// 声明一个就行
|
// 声明一个就行
|
||||||
static OpenClient client = new OpenClient(url, appId, privateKey);
|
static OpenClient client = new OpenClient(url, appId, privateKey, publicKeyPlatform);
|
||||||
|
|
||||||
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
|
@@ -13,10 +13,6 @@ namespace SDKCSharp.Request
|
|||||||
public abstract class BaseRequest<T>
|
public abstract class BaseRequest<T>
|
||||||
{
|
{
|
||||||
private string method;
|
private string method;
|
||||||
private string format = SdkConfig.FORMAT_TYPE;
|
|
||||||
private Encoding charset = SdkConfig.CHARSET;
|
|
||||||
private SignType signType = SdkConfig.SIGN_TYPE;
|
|
||||||
private string timestamp = DateTime.Now.ToString(SdkConfig.TIMESTAMP_PATTERN);
|
|
||||||
private string version;
|
private string version;
|
||||||
|
|
||||||
private string bizContent;
|
private string bizContent;
|
||||||
@@ -30,8 +26,6 @@ namespace SDKCSharp.Request
|
|||||||
public string BizContent { set => bizContent = value; }
|
public string BizContent { set => bizContent = value; }
|
||||||
public object BizModel { set => bizModel = value; }
|
public object BizModel { set => bizModel = value; }
|
||||||
public string Version { get => version; set => version = value; }
|
public string Version { get => version; set => version = value; }
|
||||||
public Encoding Charset { get => charset; set => charset = value; }
|
|
||||||
public SignType SignType { get => signType; set => signType = value; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回接口名
|
/// 返回接口名
|
||||||
@@ -45,7 +39,7 @@ namespace SDKCSharp.Request
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual string GetVersion()
|
public virtual string GetVersion()
|
||||||
{
|
{
|
||||||
return SdkConfig.DEFAULT_VERSION;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -66,7 +60,7 @@ namespace SDKCSharp.Request
|
|||||||
protected BaseRequest(string name, string version)
|
protected BaseRequest(string name, string version)
|
||||||
{
|
{
|
||||||
this.method = name;
|
this.method = name;
|
||||||
this.version = version == null ? SdkConfig.DEFAULT_VERSION : version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -88,23 +82,28 @@ namespace SDKCSharp.Request
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public RequestForm CreateRequestForm(OpenConfig openConfig)
|
public RequestForm CreateRequestForm(OpenConfig openConfig)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
string timestamp = DateTime.Now.ToString(openConfig.TimestampPattern);
|
||||||
dict[openConfig.MethodName] = this.Method;
|
string v = this.version ?? openConfig.DefaultVersion;
|
||||||
dict[openConfig.FormatName] = this.format;
|
|
||||||
dict[openConfig.CharsetName] = this.charset.BodyName;
|
|
||||||
dict[openConfig.SignTypeName] = this.signType.ToString();
|
|
||||||
dict[openConfig.TimestampName] = this.timestamp;
|
|
||||||
dict[openConfig.VersionName] = this.version;
|
|
||||||
|
|
||||||
// 业务参数
|
// 业务参数
|
||||||
String biz_content = BuildBizContent();
|
string biz_content = BuildBizContent();
|
||||||
|
|
||||||
dict[openConfig.DataName] = biz_content;
|
Dictionary<string, string> dict = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
[openConfig.MethodName] = this.Method,
|
||||||
|
[openConfig.FormatName] = openConfig.FormatType,
|
||||||
|
[openConfig.CharsetName] = openConfig.Charset.BodyName,
|
||||||
|
[openConfig.SignTypeName] = openConfig.SignType.ToString(),
|
||||||
|
[openConfig.TimestampName] = timestamp,
|
||||||
|
[openConfig.VersionName] = v,
|
||||||
|
[openConfig.DataName] = biz_content
|
||||||
|
};
|
||||||
|
|
||||||
RequestForm requestForm = new RequestForm(dict);
|
RequestForm requestForm = new RequestForm(dict)
|
||||||
requestForm.Charset = this.charset;
|
{
|
||||||
requestForm.RequestMethod = GetRequestMethod();
|
Charset = openConfig.Charset,
|
||||||
requestForm.Files = this.files;
|
RequestMethod = GetRequestMethod(),
|
||||||
|
Files = this.files
|
||||||
|
};
|
||||||
return requestForm;
|
return requestForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using SDKCSharp.Request;
|
||||||
|
|
||||||
namespace SDKCSharp.Utility
|
namespace SDKCSharp.Utility
|
||||||
{
|
{
|
||||||
@@ -36,6 +37,7 @@ namespace SDKCSharp.Utility
|
|||||||
return JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
|
return JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 对象转换成json字符串
|
/// 对象转换成json字符串
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -2,13 +2,14 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace SDKCSharp.Utility
|
namespace SDKCSharp.Utility
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 签名工具类
|
/// 签名工具类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SignUtil
|
public static class SignUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -26,6 +27,13 @@ namespace SDKCSharp.Utility
|
|||||||
return rsa.Sign(content);
|
return rsa.Sign(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool RsaCheck(string content, string sign, string publicKeyPlatform, Encoding charset,
|
||||||
|
SignType signType)
|
||||||
|
{
|
||||||
|
RSAHelper rsa = new RSAHelper(signType, charset, null, publicKeyPlatform);
|
||||||
|
return rsa.Verify(content, sign);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构建签名内容
|
/// 构建签名内容
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -53,5 +61,33 @@ namespace SDKCSharp.Utility
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建签名内容
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The sign content.</returns>
|
||||||
|
/// <param name="parameters">Parameters.</param>
|
||||||
|
public static string GetSignContentObject(IDictionary<string, object> parameters)
|
||||||
|
{
|
||||||
|
// 第一步:把字典按Key的字母顺序排序
|
||||||
|
IDictionary<string, object> sortedParams = new SortedDictionary<string, object>(parameters);
|
||||||
|
IEnumerator<KeyValuePair<string, object>> dem = sortedParams.GetEnumerator();
|
||||||
|
|
||||||
|
// 第二步:把所有参数名和参数值串在一起
|
||||||
|
StringBuilder query = new StringBuilder("");
|
||||||
|
while (dem.MoveNext())
|
||||||
|
{
|
||||||
|
string key = dem.Current.Key;
|
||||||
|
string value = Convert.ToString(dem.Current.Value);
|
||||||
|
value = Regex.Replace(value, @"\s", "");
|
||||||
|
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
query.Append(key).Append("=").Append(value).Append("&");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string content = query.ToString().Substring(0, query.Length - 1);
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,11 +5,15 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.gitee.sop.sdk.common.DataNameBuilder;
|
import com.gitee.sop.sdk.common.DataNameBuilder;
|
||||||
import com.gitee.sop.sdk.common.OpenConfig;
|
import com.gitee.sop.sdk.common.OpenConfig;
|
||||||
import com.gitee.sop.sdk.common.RequestForm;
|
import com.gitee.sop.sdk.common.RequestForm;
|
||||||
|
import com.gitee.sop.sdk.common.SopSdkConstants;
|
||||||
|
import com.gitee.sop.sdk.common.SopSdkErrors;
|
||||||
import com.gitee.sop.sdk.exception.SdkException;
|
import com.gitee.sop.sdk.exception.SdkException;
|
||||||
import com.gitee.sop.sdk.request.BaseRequest;
|
import com.gitee.sop.sdk.request.BaseRequest;
|
||||||
import com.gitee.sop.sdk.response.BaseResponse;
|
import com.gitee.sop.sdk.response.BaseResponse;
|
||||||
|
import com.gitee.sop.sdk.response.ErrorResponse;
|
||||||
import com.gitee.sop.sdk.sign.SopSignException;
|
import com.gitee.sop.sdk.sign.SopSignException;
|
||||||
import com.gitee.sop.sdk.sign.SopSignature;
|
import com.gitee.sop.sdk.sign.SopSignature;
|
||||||
|
import com.gitee.sop.sdk.sign.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -25,33 +29,46 @@ public class OpenClient {
|
|||||||
private static final Log log = LogFactory.getLog(OpenClient.class);
|
private static final Log log = LogFactory.getLog(OpenClient.class);
|
||||||
|
|
||||||
private static final OpenConfig DEFAULT_CONFIG = new OpenConfig();
|
private static final OpenConfig DEFAULT_CONFIG = new OpenConfig();
|
||||||
private static final String ERROR_RESPONSE_KEY = "error_response";
|
|
||||||
|
|
||||||
private String url;
|
private String url;
|
||||||
private String appId;
|
private String appId;
|
||||||
private String privateKey;
|
private String privateKey;
|
||||||
|
/**
|
||||||
|
* 开放平台提供的公钥
|
||||||
|
*/
|
||||||
|
private String publicKeyPlatform;
|
||||||
|
|
||||||
private OpenConfig openConfig;
|
private OpenConfig openConfig;
|
||||||
private OpenRequest openRequest;
|
private OpenRequest openRequest;
|
||||||
private DataNameBuilder dataNameBuilder;
|
private DataNameBuilder dataNameBuilder;
|
||||||
|
|
||||||
public OpenClient(String url, String appId, String privateKey) {
|
public OpenClient(String url, String appId, String privateKeyIsv) {
|
||||||
this(url, appId, privateKey, DEFAULT_CONFIG);
|
this(url, appId, privateKeyIsv, DEFAULT_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenClient(String url, String appId, String privateKey, OpenConfig openConfig) {
|
public OpenClient(String url, String appId, String privateKeyIsv, String publicKeyPlatform) {
|
||||||
|
this(url, appId, privateKeyIsv);
|
||||||
|
this.publicKeyPlatform = publicKeyPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenClient(String url, String appId, String privateKeyIsv, OpenConfig openConfig) {
|
||||||
if (openConfig == null) {
|
if (openConfig == null) {
|
||||||
throw new IllegalArgumentException("openConfig不能为null");
|
throw new IllegalArgumentException("openConfig不能为null");
|
||||||
}
|
}
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.appId = appId;
|
this.appId = appId;
|
||||||
this.privateKey = privateKey;
|
this.privateKey = privateKeyIsv;
|
||||||
this.openConfig = openConfig;
|
this.openConfig = openConfig;
|
||||||
|
|
||||||
this.openRequest = new OpenRequest(openConfig);
|
this.openRequest = new OpenRequest(openConfig);
|
||||||
this.dataNameBuilder = openConfig.getDataNameBuilder();
|
this.dataNameBuilder = openConfig.getDataNameBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OpenClient(String url, String appId, String privateKeyIsv, String publicKeyPlatform, OpenConfig openConfig) {
|
||||||
|
this(url, appId, privateKeyIsv, openConfig);
|
||||||
|
this.publicKeyPlatform = publicKeyPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求接口
|
* 请求接口
|
||||||
*
|
*
|
||||||
@@ -83,7 +100,7 @@ public class OpenClient {
|
|||||||
String content = SopSignature.getSignContent(form);
|
String content = SopSignature.getSignContent(form);
|
||||||
String sign = null;
|
String sign = null;
|
||||||
try {
|
try {
|
||||||
sign = SopSignature.rsa256Sign(content, privateKey, "utf-8");
|
sign = SopSignature.rsaSign(content, privateKey, openConfig.getCharset(), openConfig.getSignType());
|
||||||
} catch (SopSignException e) {
|
} catch (SopSignException e) {
|
||||||
throw new SdkException("构建签名错误", e);
|
throw new SdkException("构建签名错误", e);
|
||||||
}
|
}
|
||||||
@@ -109,17 +126,61 @@ public class OpenClient {
|
|||||||
|
|
||||||
protected <T extends BaseResponse> T parseResponse(String resp, BaseRequest<T> request) {
|
protected <T extends BaseResponse> T parseResponse(String resp, BaseRequest<T> request) {
|
||||||
String method = request.getMethod();
|
String method = request.getMethod();
|
||||||
String dataName = dataNameBuilder.build(method);
|
String rootNodeName = dataNameBuilder.build(method);
|
||||||
JSONObject jsonObject = JSON.parseObject(resp);
|
JSONObject jsonObject = JSON.parseObject(resp);
|
||||||
boolean errorResponse = jsonObject.containsKey(ERROR_RESPONSE_KEY);
|
String errorResponseName = this.openConfig.getErrorResponseName();
|
||||||
|
boolean errorResponse = jsonObject.containsKey(errorResponseName);
|
||||||
if (errorResponse) {
|
if (errorResponse) {
|
||||||
dataName = ERROR_RESPONSE_KEY;
|
rootNodeName = errorResponseName;
|
||||||
|
}
|
||||||
|
JSONObject data = jsonObject.getJSONObject(rootNodeName);
|
||||||
|
String sign = jsonObject.getString(openConfig.getSignName());
|
||||||
|
// 是否要验证返回的sign
|
||||||
|
if (StringUtils.areNotEmpty(sign, publicKeyPlatform)) {
|
||||||
|
String signContent = buildBizJson(rootNodeName, resp);
|
||||||
|
if (!this.checkResponseSign(signContent, sign, publicKeyPlatform)) {
|
||||||
|
ErrorResponse error = SopSdkErrors.CHECK_RESPONSE_SIGN_ERROR.getErrorResponse();
|
||||||
|
data = JSON.parseObject(JSON.toJSONString(error));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
JSONObject data = jsonObject.getJSONObject(dataName);
|
|
||||||
T t = data.toJavaObject(request.getResponseClass());
|
T t = data.toJavaObject(request.getResponseClass());
|
||||||
t.setBody(data.toJSONString());
|
t.setBody(data.toJSONString());
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String buildBizJson(String rootNodeName, String body) {
|
||||||
|
int indexOfRootNode = body.indexOf(rootNodeName);
|
||||||
|
if (indexOfRootNode < 0) {
|
||||||
|
rootNodeName = SopSdkConstants.ERROR_RESPONSE_KEY;
|
||||||
|
indexOfRootNode = body.indexOf(rootNodeName);
|
||||||
|
}
|
||||||
|
String result = null;
|
||||||
|
if (indexOfRootNode > 0) {
|
||||||
|
result = buildJsonNodeData(body, rootNodeName, indexOfRootNode);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String buildJsonNodeData(String body, String rootNodeName, int indexOfRootNode) {
|
||||||
|
int signDataStartIndex = indexOfRootNode + rootNodeName.length() + 2;
|
||||||
|
int indexOfSign = body.indexOf("\"" + openConfig.getSignName() + "\"");
|
||||||
|
if (indexOfSign < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int length = indexOfSign - 1;
|
||||||
|
return body.substring(signDataStartIndex, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T extends BaseResponse> boolean checkResponseSign(String signContent, String sign, String publicKeyPlatform) {
|
||||||
|
try {
|
||||||
|
String charset = this.openConfig.getCharset();
|
||||||
|
String signType = this.openConfig.getSignType();
|
||||||
|
return SopSignature.rsaCheck(signContent, sign, publicKeyPlatform, charset, signType);
|
||||||
|
} catch (SopSignException e) {
|
||||||
|
log.error("验证服务端sign出错,signContent:" + signContent, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,9 @@ import com.alibaba.fastjson.JSON;
|
|||||||
import com.gitee.sop.sdk.common.OpenConfig;
|
import com.gitee.sop.sdk.common.OpenConfig;
|
||||||
import com.gitee.sop.sdk.common.RequestForm;
|
import com.gitee.sop.sdk.common.RequestForm;
|
||||||
import com.gitee.sop.sdk.common.RequestMethod;
|
import com.gitee.sop.sdk.common.RequestMethod;
|
||||||
|
import com.gitee.sop.sdk.common.SopSdkErrors;
|
||||||
import com.gitee.sop.sdk.common.UploadFile;
|
import com.gitee.sop.sdk.common.UploadFile;
|
||||||
import com.gitee.sop.sdk.response.BaseResponse;
|
import com.gitee.sop.sdk.response.ErrorResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
@@ -20,8 +21,6 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class OpenRequest {
|
public class OpenRequest {
|
||||||
|
|
||||||
private static final String HTTP_ERROR_CODE = "-400";
|
|
||||||
|
|
||||||
private OpenHttp openHttp;
|
private OpenHttp openHttp;
|
||||||
|
|
||||||
public OpenRequest(OpenConfig openConfig) {
|
public OpenRequest(OpenConfig openConfig) {
|
||||||
@@ -69,14 +68,7 @@ public class OpenRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String causeException(Exception e) {
|
protected String causeException(Exception e) {
|
||||||
ErrorResponse result = new ErrorResponse();
|
ErrorResponse result = SopSdkErrors.HTTP_ERROR.getErrorResponse();
|
||||||
result.setCode(HTTP_ERROR_CODE);
|
|
||||||
result.setSubCode(HTTP_ERROR_CODE);
|
|
||||||
result.setSubMsg(e.getMessage());
|
|
||||||
result.setMsg(e.getMessage());
|
|
||||||
return JSON.toJSONString(result);
|
return JSON.toJSONString(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ErrorResponse extends BaseResponse {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ package com.gitee.sop.sdk.common;
|
|||||||
public class DefaultDataNameBuilder implements DataNameBuilder {
|
public class DefaultDataNameBuilder implements DataNameBuilder {
|
||||||
private static final char DOT = '.';
|
private static final char DOT = '.';
|
||||||
private static final char UNDERLINE = '_';
|
private static final char UNDERLINE = '_';
|
||||||
private static final String DATA_SUFFIX = "_response";
|
private static final String DATA_SUFFIX = SopSdkConstants.DATA_SUFFIX;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String build(String method) {
|
public String build(String method) {
|
||||||
|
@@ -7,10 +7,21 @@ import lombok.Data;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class OpenConfig {
|
public class OpenConfig {
|
||||||
|
public static DataNameBuilder DATA_NAME_BUILDER = new DefaultDataNameBuilder();
|
||||||
|
|
||||||
/** 成功返回码值 */
|
/** 成功返回码值 */
|
||||||
private String successCode = SdkConfig.SUCCESS_CODE;
|
private String successCode = "10000";
|
||||||
/** 默认版本号 */
|
/** 默认版本号 */
|
||||||
private String defaultVersion = SdkConfig.DEFAULT_VERSION;
|
private String defaultVersion = "1.0";
|
||||||
|
/** 字符编码 */
|
||||||
|
private String charset = "UTF-8";
|
||||||
|
/** 签名方式 */
|
||||||
|
private String signType = "RSA2";
|
||||||
|
/** 格式类型名称 */
|
||||||
|
private String formatType = "json";
|
||||||
|
/** 时间戳格式 */
|
||||||
|
private String timestampPattern = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
/** 接口属性名 */
|
/** 接口属性名 */
|
||||||
private String methodName = "method";
|
private String methodName = "method";
|
||||||
/** 版本号名称 */
|
/** 版本号名称 */
|
||||||
@@ -23,22 +34,21 @@ public class OpenConfig {
|
|||||||
private String dataName = "biz_content";
|
private String dataName = "biz_content";
|
||||||
/** 时间戳名称 */
|
/** 时间戳名称 */
|
||||||
private String timestampName = "timestamp";
|
private String timestampName = "timestamp";
|
||||||
/** 时间戳格式 */
|
|
||||||
private String timestampPattern = "yyyy-MM-dd HH:mm:ss";
|
|
||||||
/** 签名串名称 */
|
/** 签名串名称 */
|
||||||
private String signName = "sign";
|
private String signName = "sign";
|
||||||
/** 签名类型名称 */
|
/** 签名类型名称 */
|
||||||
private String signTypeName = "sign_type";
|
private String signTypeName = "sign_type";
|
||||||
/** 格式化名称 */
|
/** 格式化名称 */
|
||||||
private String formatName = "format";
|
private String formatName = "format";
|
||||||
/** 格式类型名称 */
|
|
||||||
private String formatType = "json";
|
|
||||||
/** accessToken名称 */
|
/** accessToken名称 */
|
||||||
private String accessTokenName = "app_auth_token";
|
private String accessTokenName = "app_auth_token";
|
||||||
/** 国际化语言 */
|
/** 国际化语言 */
|
||||||
private String locale = "zh-CN";
|
private String locale = "zh-CN";
|
||||||
/** 响应code名称 */
|
/** 响应code名称 */
|
||||||
private String responseCodeName = "code";
|
private String responseCodeName = "code";
|
||||||
|
/** 错误响应节点 */
|
||||||
|
private String errorResponseName = "error_response";
|
||||||
|
|
||||||
/** 请求超时时间 */
|
/** 请求超时时间 */
|
||||||
private int connectTimeoutSeconds = 10;
|
private int connectTimeoutSeconds = 10;
|
||||||
/** http读取超时时间 */
|
/** http读取超时时间 */
|
||||||
@@ -49,5 +59,5 @@ public class OpenConfig {
|
|||||||
/**
|
/**
|
||||||
* 构建数据节点名称
|
* 构建数据节点名称
|
||||||
*/
|
*/
|
||||||
private DataNameBuilder dataNameBuilder = SdkConfig.dataNameBuilder;
|
private DataNameBuilder dataNameBuilder = DATA_NAME_BUILDER;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
package com.gitee.sop.sdk.common;
|
package com.gitee.sop.sdk.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 已废弃,使用com.gitee.sop.sdk.common.OpenConfig
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public class SdkConfig {
|
public class SdkConfig {
|
||||||
|
|
||||||
public static String SUCCESS_CODE = "10000";
|
public static String SUCCESS_CODE = "10000";
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
package com.gitee.sop.sdk.common;
|
||||||
|
|
||||||
|
public class SopSdkConstants {
|
||||||
|
public static String DATA_SUFFIX = "_response";
|
||||||
|
|
||||||
|
public static String ERROR_RESPONSE_KEY = "error_response";
|
||||||
|
}
|
@@ -0,0 +1,56 @@
|
|||||||
|
package com.gitee.sop.sdk.common;
|
||||||
|
|
||||||
|
import com.gitee.sop.sdk.response.ErrorResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
public enum SopSdkErrors {
|
||||||
|
/**
|
||||||
|
* 网络错误
|
||||||
|
*/
|
||||||
|
HTTP_ERROR("836875001", "网络错误"),
|
||||||
|
/**
|
||||||
|
* 验证返回sign错误
|
||||||
|
*/
|
||||||
|
CHECK_RESPONSE_SIGN_ERROR("836875002", "验证服务端sign出错")
|
||||||
|
;
|
||||||
|
|
||||||
|
SopSdkErrors(String code, String msg) {
|
||||||
|
this.code = code;
|
||||||
|
this.msg = msg;
|
||||||
|
this.subCode = code;
|
||||||
|
this.subMsg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErrorResponse getErrorResponse() {
|
||||||
|
ErrorResponse errorResponse = new ErrorResponse();
|
||||||
|
errorResponse.setCode(code);
|
||||||
|
errorResponse.setSubCode(subCode);
|
||||||
|
errorResponse.setSubMsg(subMsg);
|
||||||
|
errorResponse.setMsg(msg);
|
||||||
|
return errorResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private String msg;
|
||||||
|
private String subCode;
|
||||||
|
private String subMsg;
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubCode() {
|
||||||
|
return subCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubMsg() {
|
||||||
|
return subMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
|
|||||||
import com.gitee.sop.sdk.common.OpenConfig;
|
import com.gitee.sop.sdk.common.OpenConfig;
|
||||||
import com.gitee.sop.sdk.common.RequestForm;
|
import com.gitee.sop.sdk.common.RequestForm;
|
||||||
import com.gitee.sop.sdk.common.RequestMethod;
|
import com.gitee.sop.sdk.common.RequestMethod;
|
||||||
import com.gitee.sop.sdk.common.SdkConfig;
|
|
||||||
import com.gitee.sop.sdk.common.UploadFile;
|
import com.gitee.sop.sdk.common.UploadFile;
|
||||||
import com.gitee.sop.sdk.response.BaseResponse;
|
import com.gitee.sop.sdk.response.BaseResponse;
|
||||||
import com.gitee.sop.sdk.util.ClassUtil;
|
import com.gitee.sop.sdk.util.ClassUtil;
|
||||||
@@ -36,10 +35,6 @@ import java.util.Map;
|
|||||||
public abstract class BaseRequest<T extends BaseResponse> {
|
public abstract class BaseRequest<T extends BaseResponse> {
|
||||||
|
|
||||||
private String method;
|
private String method;
|
||||||
private String format = SdkConfig.FORMAT_TYPE;
|
|
||||||
private String charset = SdkConfig.CHARSET;
|
|
||||||
private String signType = SdkConfig.SIGN_TYPE;
|
|
||||||
private String timestamp = new SimpleDateFormat(SdkConfig.TIMESTAMP_PATTERN).format(new Date());
|
|
||||||
private String version;
|
private String version;
|
||||||
|
|
||||||
private String bizContent;
|
private String bizContent;
|
||||||
@@ -50,11 +45,10 @@ public abstract class BaseRequest<T extends BaseResponse> {
|
|||||||
*/
|
*/
|
||||||
private List<UploadFile> files;
|
private List<UploadFile> files;
|
||||||
|
|
||||||
private Class<T> responseClass;
|
private Class<T> responseClass = (Class<T>) ClassUtil.getSuperClassGenricType(this.getClass(), 0);;
|
||||||
|
|
||||||
protected abstract String method();
|
protected abstract String method();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public BaseRequest() {
|
public BaseRequest() {
|
||||||
this.setMethodVersion(this.method(), this.version());
|
this.setMethodVersion(this.method(), this.version());
|
||||||
}
|
}
|
||||||
@@ -65,16 +59,16 @@ public abstract class BaseRequest<T extends BaseResponse> {
|
|||||||
|
|
||||||
private void setMethodVersion(String method, String version) {
|
private void setMethodVersion(String method, String version) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.version = version == null ? SdkConfig.DEFAULT_VERSION : version;
|
this.version = version;
|
||||||
this.responseClass = (Class<T>) ClassUtil.getSuperClassGenricType(this.getClass(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String version() {
|
protected String version() {
|
||||||
return SdkConfig.DEFAULT_VERSION;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加上传文件
|
* 添加上传文件
|
||||||
|
*
|
||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
public void addFile(UploadFile file) {
|
public void addFile(UploadFile file) {
|
||||||
@@ -88,11 +82,13 @@ public abstract class BaseRequest<T extends BaseResponse> {
|
|||||||
// 公共请求参数
|
// 公共请求参数
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
params.put(openConfig.getMethodName(), this.method);
|
params.put(openConfig.getMethodName(), this.method);
|
||||||
params.put(openConfig.getFormatName(), this.format);
|
params.put(openConfig.getFormatName(), openConfig.getFormatType());
|
||||||
params.put(openConfig.getCharsetName(), this.charset);
|
params.put(openConfig.getCharsetName(), openConfig.getCharset());
|
||||||
params.put(openConfig.getSignTypeName(), this.signType);
|
params.put(openConfig.getSignTypeName(), openConfig.getSignType());
|
||||||
params.put(openConfig.getTimestampName(), this.timestamp);
|
String timestamp = new SimpleDateFormat(openConfig.getTimestampPattern()).format(new Date());
|
||||||
params.put(openConfig.getVersionName(), this.version);
|
params.put(openConfig.getTimestampName(), timestamp);
|
||||||
|
String v = this.version == null ? openConfig.getDefaultVersion() : this.version;
|
||||||
|
params.put(openConfig.getVersionName(), v);
|
||||||
|
|
||||||
// 业务参数
|
// 业务参数
|
||||||
String biz_content = buildBizContent();
|
String biz_content = buildBizContent();
|
||||||
@@ -101,7 +97,7 @@ public abstract class BaseRequest<T extends BaseResponse> {
|
|||||||
|
|
||||||
RequestForm requestForm = new RequestForm(params);
|
RequestForm requestForm = new RequestForm(params);
|
||||||
requestForm.setRequestMethod(getRequestMethod());
|
requestForm.setRequestMethod(getRequestMethod());
|
||||||
requestForm.setCharset(this.charset);
|
requestForm.setCharset(openConfig.getCharset());
|
||||||
requestForm.setFiles(this.files);
|
requestForm.setFiles(this.files);
|
||||||
return requestForm;
|
return requestForm;
|
||||||
}
|
}
|
||||||
@@ -120,6 +116,7 @@ public abstract class BaseRequest<T extends BaseResponse> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定版本号
|
* 指定版本号
|
||||||
|
*
|
||||||
* @param version
|
* @param version
|
||||||
*/
|
*/
|
||||||
public void setVersion(String version) {
|
public void setVersion(String version) {
|
||||||
@@ -144,9 +141,11 @@ public abstract class BaseRequest<T extends BaseResponse> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定HTTP请求method,默认POST
|
* 指定HTTP请求method,默认POST
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected RequestMethod getRequestMethod() {
|
protected RequestMethod getRequestMethod() {
|
||||||
return RequestMethod.POST;
|
return RequestMethod.POST;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
package com.gitee.sop.sdk.response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
public class ErrorResponse extends BaseResponse {
|
||||||
|
}
|
@@ -53,14 +53,14 @@ public class SopSignature {
|
|||||||
* @param sortedParams
|
* @param sortedParams
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getSignContent(Map<String, String> sortedParams) {
|
public static String getSignContent(Map<String, ?> sortedParams) {
|
||||||
StringBuffer content = new StringBuffer();
|
StringBuffer content = new StringBuffer();
|
||||||
List<String> keys = new ArrayList<String>(sortedParams.keySet());
|
List<String> keys = new ArrayList<String>(sortedParams.keySet());
|
||||||
Collections.sort(keys);
|
Collections.sort(keys);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < keys.size(); i++) {
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
String key = keys.get(i);
|
String key = keys.get(i);
|
||||||
String value = sortedParams.get(key);
|
String value = String.valueOf(sortedParams.get(key));
|
||||||
if (StringUtils.areNotEmpty(key, value)) {
|
if (StringUtils.areNotEmpty(key, value)) {
|
||||||
content.append((index == 0 ? "" : "&") + key + "=" + value);
|
content.append((index == 0 ? "" : "&") + key + "=" + value);
|
||||||
index++;
|
index++;
|
||||||
@@ -210,7 +210,7 @@ public class SopSignature {
|
|||||||
return content.toString();
|
return content.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSignCheckContentV2(Map<String, String> params) {
|
public static String getSignCheckContentV2(Map<String, ?> params) {
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ public class SopSignature {
|
|||||||
|
|
||||||
for (int i = 0; i < keys.size(); i++) {
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
String key = keys.get(i);
|
String key = keys.get(i);
|
||||||
String value = params.get(key);
|
String value = String.valueOf(params.get(key));
|
||||||
content.append((i == 0 ? "" : "&") + key + "=" + value);
|
content.append((i == 0 ? "" : "&") + key + "=" + value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,9 +254,9 @@ public class SopSignature {
|
|||||||
return rsaCheckContent(content, sign, publicKey, charset);
|
return rsaCheckContent(content, sign, publicKey, charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean rsaCheckV2(Map<String, String> params, String publicKey,
|
public static boolean rsaCheckV2(Map<String, ?> params, String publicKey,
|
||||||
String charset,String signType) throws SopSignException {
|
String charset,String signType) throws SopSignException {
|
||||||
String sign = params.get("sign");
|
String sign = String.valueOf(params.get("sign"));
|
||||||
String content = getSignCheckContentV2(params);
|
String content = getSignCheckContentV2(params);
|
||||||
|
|
||||||
return rsaCheck(content, sign, publicKey, charset,signType);
|
return rsaCheck(content, sign, publicKey, charset,signType);
|
||||||
|
@@ -24,12 +24,14 @@ import java.util.Map;
|
|||||||
public class SdkTest extends TestCase {
|
public class SdkTest extends TestCase {
|
||||||
String url = "http://localhost:8081/api"; // zuul
|
String url = "http://localhost:8081/api"; // zuul
|
||||||
String appId = "2019032617262200001";
|
String appId = "2019032617262200001";
|
||||||
// 支付宝私钥
|
/** 开发者私钥 */
|
||||||
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
|
String privateKeyIsv = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
|
||||||
|
/** 开放平台提供的公钥
|
||||||
|
* 前往SOP-ADMIN,ISV管理--秘钥管理,生成平台提供的公私钥,然后把【平台公钥】放到这里 */
|
||||||
|
String publicKeyPlatform = "";
|
||||||
|
|
||||||
// 声明一个就行
|
// 声明一个就行
|
||||||
OpenClient client = new OpenClient(url, appId, privateKey);
|
OpenClient client = new OpenClient(url, appId, privateKeyIsv, publicKeyPlatform);
|
||||||
|
|
||||||
// 标准用法
|
// 标准用法
|
||||||
@Test
|
@Test
|
||||||
|
Reference in New Issue
Block a user