AIMS/AIMSExtension/Sign/DataSignClient.cs
2023-08-03 12:55:03 +08:00

203 lines
8.0 KiB
C#

#if STJ
#else
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
#endif
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
//using System.Text.Json;
using System.Threading.Tasks;
namespace AIMS.Infrastructure.CA
{
public class DataSignClient
{
private static HttpClient _httpClient;
private readonly string _baseUrl;
private readonly string _accessToken;
private readonly string _signature;
private readonly string _timestamp;
private readonly SignConfig signConfig;
public DataSignClient(SignConfig signConfig)
{
_baseUrl = signConfig.Url.TrimEnd('/');
this.signConfig = signConfig;
if (_httpClient == null)
{
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri(signConfig.Url.TrimEnd('/'));
}
}
public DataSignClient(HttpClient httpClient, string accessToken, string signature, string timestamp)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_accessToken = accessToken ?? throw new ArgumentNullException(nameof(accessToken));
_signature = signature ?? throw new ArgumentNullException(nameof(signature));
_timestamp = timestamp ?? throw new ArgumentNullException(nameof(timestamp));
}
// 封装业务数据签名的API
public SignatureResponse SignData(SignatureRequest request)
{
var requestUrl = $"/binary/sign/ZPTFYY";
var httpResponse = BusinessDataSign(requestUrl, request.Data, request.Signatory, request.DataType, request.SigAlgType);
return httpResponse;
}
private SignatureResponse BusinessDataSign(string signUrl,
byte[] fileStream, Signatory signatory,
string dataType = null, string sigAlgType = null, string fileName = null)
{
if (signUrl == null) throw new ArgumentNullException(nameof(signUrl));
if (fileStream == null) throw new ArgumentNullException(nameof(fileStream));
if (signatory == null) throw new ArgumentNullException(nameof(signatory));
var request = new HttpRequestMessage(HttpMethod.Post, signUrl);
Sign(request);
var multiPartContent = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(fileStream);
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
multiPartContent.Add(fileContent, "data", fileName ?? "filename"); // replace "filename" with actual filename
var signatoryContent = new StringContent(Serialize(signatory));
multiPartContent.Add(signatoryContent, "signatory");
multiPartContent.Add(new StringContent(dataType), "dataType");
multiPartContent.Add(new StringContent(sigAlgType), "sigAlgType");
request.Content = multiPartContent;
//File.WriteAllText("log.http", request.());
var response = _httpClient.SendAsync(request);
//response.EnsureSuccessStatusCode();
var responseContent = response.Result.Content.ReadAsStringAsync().Result;
Console.Out.WriteLine(responseContent);
request.Dispose();
response.Dispose();
return Deserialize<SignatureResponse>(responseContent);
}
// 封装获取数据签名详细信息的API
public DetailResponse GetSignDetail(DetailRequest request)
{
var requestUrl = $"{_baseUrl}/binary/detail/ZPTFYY?id={request.Id}&bizId={request.BizId}";
var httpResponse = GetDetail(requestUrl);
return httpResponse;
}
// 封装下载数据签名原文的API
public Stream DownloadOriginalData(DownloadRequest request)
{
var requestUrl = $"{_baseUrl}/binary/download?id={request.Id}&bizId={request.BizId}";
var httpResponse = DownloadFile(requestUrl);
return httpResponse;
}
// 封装下载存证报告的API
public Stream DownloadEvidence(EvidenceDownloadRequest request)
{
var requestUrl = $"{_baseUrl}/evidence/download?contractId={request.ContractId}&bizId={request.BizId}";
var httpResponse = DownloadFile(requestUrl);
return httpResponse;
}
private DetailResponse GetDetail(string detailUrl)
{
if (detailUrl == null) throw new ArgumentNullException(nameof(detailUrl));
var request = new HttpRequestMessage(HttpMethod.Get, detailUrl);
Sign(request);
var response = _httpClient.SendAsync(request).Result;
response.EnsureSuccessStatusCode();
var responseContent = response.Content.ReadAsStringAsync().Result;
request.Dispose();
response.Dispose();
return Deserialize<DetailResponse>(responseContent);
}
private Stream DownloadFile(string downloadUrl)
{
if (downloadUrl == null) throw new ArgumentNullException(nameof(downloadUrl));
var request = new HttpRequestMessage(HttpMethod.Get, downloadUrl);
Sign(request);
var response = _httpClient.SendAsync(request).Result;
response.EnsureSuccessStatusCode();
request.Dispose();
response.Dispose();
return response.Content.ReadAsStreamAsync().Result;
}
// Add other API methods like GetDetail, Download, DownloadEvidence here
public void Sign(HttpRequestMessage request)
{
var timestamp = GenerateTimestamp();
var nonce = GenerateNonce();
var signature = GenerateSignature(timestamp, nonce);
request.Headers.TryAddWithoutValidation("x-qys-accesstoken", signConfig.AppToken);
request.Headers.TryAddWithoutValidation("x-qys-timestamp", timestamp);
request.Headers.TryAddWithoutValidation("x-qys-nonce", nonce);
request.Headers.TryAddWithoutValidation("x-qys-signature", signature);
}
#region sign
private string GenerateNonce()
{
return Guid.NewGuid().ToString("n");
}
private string GenerateTimestamp()
{
long currentMilliseconds = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds;
return currentMilliseconds.ToString();
}
static MD5 md5 = MD5.Create();
private string GenerateSignature(string timestamp, string nonce)
{
var raw = signConfig.AppToken + signConfig.AppSecret + timestamp + nonce;
var bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(raw));
return BitConverter.ToString(bytes).Replace("-", "").ToLower();
}
#endregion
#if STJ
private static System.Text.Json.JsonSerializerOptions JsonSerializerOptions = new System.Text.Json.JsonSerializerOptions(JsonSerializerDefaults.Web);
public static string Serialize<T>(T obj)
{
return System.Text.Json.JsonSerializer.Serialize(obj, JsonSerializerOptions);
}
public static T Deserialize<T>(string jsonText)
{
return System.Text.Json.JsonSerializer.Deserialize<T>(jsonText, JsonSerializerOptions);
}
#else
private static JsonSerializerSettings JsonSerializerOptions = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
};
public static string Serialize<T>(T obj)
{
return JsonConvert.SerializeObject(obj, JsonSerializerOptions);
}
public static T Deserialize<T>(string jsonText)
{
return JsonConvert.DeserializeObject<T>(jsonText, JsonSerializerOptions);
}
#endif
}
}