コード例 #1
0
        /// <summary>
        /// 添加时间请求头信息
        /// </summary>
        /// <param name="requestModel">请求信息</param>
        /// <returns></returns>
        private RequestModel AddRequestDateHeader(RequestModel requestModel)
        {
            string formatDateTime = requestModel.OverrddenDate == null || !requestModel.OverrddenDate.HasValue ?
                                    DateTime.UtcNow.ToString(ParameterConstant.DATA_TIME_FORMAT) : requestModel.OverrddenDate.Value.ToString(ParameterConstant.DATA_TIME_FORMAT);

            requestModel.AddHeader(ParameterConstant.X_JDCLOUD_DATE, formatDateTime);
            return(requestModel);
        }
コード例 #2
0
        /// <summary>
        /// 添加ContentType头信息
        /// </summary>
        /// <param name="requestModel">请求信息</param>
        /// <returns></returns>
        private RequestModel AddContentTypeHeader(RequestModel requestModel)
        {
            if (requestModel.ContentType.IsNullOrWhiteSpace())
            {
                requestModel.ContentType = ParameterConstant.MIME_JSON;
            }
            requestModel.AddHeader(ParameterConstant.CONTENT_TYPE, requestModel.ContentType);

            return(requestModel);
        }
コード例 #3
0
        /// <summary>
        /// 添加host 请求信息
        /// </summary>
        /// <param name="requestModel"></param>
        /// <returns></returns>
        private RequestModel AddHostHeader(RequestModel requestModel)
        {
            string url = requestModel.Uri.Host;

            if (url.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException("the request url is not set,please check the client url config");
            }
            if (requestModel.Uri.IsDefaultPort)
            {
                requestModel.AddHeader(ParameterConstant.HOST, requestModel.Uri.Host);
            }
            else
            {
                StringBuilder signHostBuilder = new StringBuilder();
                signHostBuilder.Append(requestModel.Uri.Host).Append(":").Append(requestModel.Uri.Port);
                requestModel.AddHeader(ParameterConstant.HOST, signHostBuilder.ToString());
            }

            return(requestModel);
        }
コード例 #4
0
        public static List <TestCaseModel> GetTestCase()
        {
            //var aaa = "/`!@#$%^&*()=+/0123456789/[]\\;',<>?:\"{}|/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/-_.~"
            List <TestCaseModel> testCaseModels = new List <TestCaseModel>();

            using (FileStream fileStream = File.OpenRead("./TestCase.xlsx"))
            {
                XSSFWorkbook xSSFWorkbook = new XSSFWorkbook(fileStream);
                ISheet       sheet        = xSSFWorkbook.GetSheetAt(1);
                string       ak           = "ak";
                string       sk           = "sk";
                for (int j = 1; j < sheet.LastRowNum; j++)
                {
                    IRow row = sheet.GetRow(j);
                    if (row != null)
                    {
                        RequestModel requestModel = new RequestModel();
                        //string host = "apigw-internal-dev.cn-north-1.jcloudcs.com";
                        var port = 8000;
                        requestModel.RequestPort = port;

                        requestModel.RegionName = row.Cells[5].StringCellValue;
                        if (string.IsNullOrWhiteSpace(requestModel.RegionName))
                        {
                            break;
                        }
                        requestModel.ServiceName = row.Cells[6].StringCellValue;
                        string host = row.Cells[7].StringCellValue;
                        if (row.Cells[2].StringCellValue == "header的value包含多个值")
                        {
                            Console.WriteLine(row.Cells[2].StringCellValue);
                        }
                        string header = row.Cells[8].StringCellValue;
                        Dictionary <string, Object> headerDictionary =
                            JsonConvert.DeserializeObject <Dictionary <string, Object> >(header);
                        if (headerDictionary != null && headerDictionary.Count > 0)
                        {
                            foreach (var item in headerDictionary)
                            {
                                if (item.Value is string)
                                {
                                    requestModel.AddHeader(item.Key, item.Value.ToString());
                                }
                                else if (item.Value is List <string> )
                                {
                                    foreach (var valueItem in (List <string>)item.Value)
                                    {
                                        requestModel.AddHeader(item.Key, valueItem);
                                    }
                                }
                                else if (item.Value.GetType() == typeof(JArray))
                                {
                                    foreach (var valueItem in (JArray)item.Value)
                                    {
                                        requestModel.AddHeader(item.Key, valueItem.ToString());
                                    }
                                }
                            }
                        }
                        string requestPath = row.Cells[9].StringCellValue;
                        requestModel.ResourcePath = requestPath;
                        string queryString = row.Cells[10].StringCellValue;
                        if (!string.IsNullOrWhiteSpace(queryString) && queryString != "空")
                        {
                            requestModel.QueryParameters = queryString;
                        }
                        if (!requestPath.StartsWith("/"))
                        {
                            requestPath = $"/{requestPath}";
                        }
                        if (queryString == "空")
                        {
                            queryString = string.Empty;
                        }
                        if (!string.IsNullOrWhiteSpace(queryString) && !queryString.StartsWith("?"))
                        {
                            queryString = $"?{queryString}";
                        }

                        string url = $"{host}{requestPath}{queryString}";
                        Uri    uri = new Uri(url);
                        requestModel.Uri        = uri;
                        requestModel.HttpMethod = row.Cells[4].StringCellValue;
                        TestCaseModel testCaseModel = new TestCaseModel();
                        testCaseModel.RequestModel     = requestModel;
                        testCaseModel.CaseName         = row.Cells[2].StringCellValue;
                        testCaseModel.CanonicalRequest = row.Cells[11].StringCellValue;
                        // testCaseModel.StringToSign = row.Cells[11].StringCellValue;
                        testCaseModel.Authorization = row.Cells[12].StringCellValue;
                        testCaseModels.Add(testCaseModel);
                    }
                }
            }
            return(testCaseModels);
        }
コード例 #5
0
        /// <summary>
        /// 扩展签名方法
        /// </summary>
        /// <param name="httpWebRequest">当前请求客户端</param>
        /// <param name="credentials">认证参数信息</param>
        /// <param name="bodyContent"></param>
        /// <param name="serviceName"></param>
        /// <param name="signType"></param>
        /// <param name="overrideDate"></param>
        /// <param name="isWriteBody"></param>
        /// <returns></returns>
        public static HttpWebRequest DoSign(this HttpWebRequest httpWebRequest, Credential credentials, string serviceName = null, object bodyContent = null, bool isWriteBody = false, JDCloudSignVersionType?signType = null, DateTime?overrideDate = null)
        {
            var byteContent = new byte[0];

            if (bodyContent != null)
            {
                if (isWriteBody)
                {
                    if (bodyContent is byte[])
                    {
                        byteContent = (byte[])bodyContent;
                    }
                    else if (bodyContent is string)
                    {
                        byteContent = System.Text.Encoding.UTF8.GetBytes((string)bodyContent);
                        //  httpWebRequest.ContentLength = byteContent.Length;
                        //  httpRequestWrite.Write(byteContent, 0, byteContent.Length);
                    }
                    else if (bodyContent is int || bodyContent is long || bodyContent is bool || bodyContent is float || bodyContent is double)
                    {
                        if (bodyContent is int)
                        {
                            byteContent = BitConverter.GetBytes((int)bodyContent);
                        }
                        else if (bodyContent is long)
                        {
                            byteContent = BitConverter.GetBytes((long)bodyContent);
                        }
                        else if (bodyContent is bool)
                        {
                            byteContent = BitConverter.GetBytes((bool)bodyContent);
                        }
                        else if (bodyContent is float)
                        {
                            byteContent = BitConverter.GetBytes((float)bodyContent);
                        }
                        else if (bodyContent is double)
                        {
                            byteContent = BitConverter.GetBytes((double)bodyContent);
                        }
                    }

                    else
                    {
                        var requestJson = JsonConvert.SerializeObject(bodyContent);
                        if (!requestJson.IsNullOrWhiteSpace())
                        {
                            byteContent = System.Text.Encoding.UTF8.GetBytes((string)bodyContent);
                        }
                    }
                }
            }
            var headers        = httpWebRequest.Headers;
            var requestUri     = httpWebRequest.RequestUri;
            var queryString    = requestUri.Query;
            var requestPath    = requestUri.AbsolutePath;
            var requestContent = bodyContent;

            var          requestMethod = httpWebRequest.Method;
            string       apiVersion    = requestUri.GetRequestVersion();
            RequestModel requestModel  = new RequestModel();

            requestModel.Content    = (byte[])byteContent.Clone();
            requestModel.ApiVersion = apiVersion;

            if (!httpWebRequest.ContentType.IsNullOrWhiteSpace())
            {
                requestModel.ContentType = httpWebRequest.ContentType.ToString();
            }
            requestModel.HttpMethod = requestMethod.ToString().ToUpper();
            var pathRegion = requestUri.GetRequestRegion();

            if (!pathRegion.IsNullOrWhiteSpace())
            {
                requestModel.RegionName = pathRegion;
            }
            else
            {
                requestModel.RegionName = ParameterConstant.DEFAULT_REGION;
            }

            requestModel.ResourcePath = requestPath;
            if (!serviceName.IsNullOrWhiteSpace())
            {
                requestModel.ServiceName = serviceName;
            }
            else
            {
                serviceName = requestUri.GetServiceName();
                if (serviceName.IsNullOrWhiteSpace())
                {
                    throw new Exception("service name not config , if you not use default endpoint please config service in sign");
                }
                requestModel.ServiceName = serviceName;
            }
            JDCloudSignVersionType jDCloudSignVersionType = GlobalConfig.GetInstance().SignVersionType;

            if (signType != null && signType.HasValue)
            {
                jDCloudSignVersionType = signType.Value;
            }
            requestModel.SignType        = jDCloudSignVersionType;
            requestModel.Uri             = requestUri;
            requestModel.QueryParameters = queryString;
            requestModel.OverrddenDate   = overrideDate;
            if (!(requestUri.Scheme.ToLower() == "http" && requestUri.Port == 80) &&
                !(requestUri.Scheme.ToLower() == "https" && requestUri.Port == 443))
            {
                requestModel.RequestPort = requestUri.Port;
            }
            foreach (string headerKeyValue in headers.Keys)
            {
                requestModel.AddHeader(headerKeyValue, headers.Get(headerKeyValue));
            }
            IJDCloudSigner     jDCloudSigner      = SignUtil.GetJDCloudSigner(jDCloudSignVersionType);
            SignedRequestModel signedRequestModel = jDCloudSigner.Sign(requestModel, credentials);
            var signedHeader = signedRequestModel.RequestHead;

            foreach (var key in signedHeader.Keys)
            {
                if (httpWebRequest.Headers.GetValues(key) == null)
                {
                    var value = signedHeader[key];
                    httpWebRequest.Headers.Add(key, value);
                }
            }
            if (byteContent.Length > 0)
            {
                httpWebRequest.ContentLength = byteContent.Length;
                using (var httpRequestWrite = httpWebRequest.GetRequestStream())
                {
                    httpRequestWrite.Write(byteContent, 0, byteContent.Length);
                }
            }
            return(httpWebRequest);
        }
コード例 #6
0
        /// <summary>
        /// do sign http request message
        /// </summary>
        /// <param name="httpRequestMessage">the http request</param>
        /// <param name="credentials">the jdcloud credentials</param>
        /// <param name="overWriteDate">over write sign data</param>
        /// <param name="signType">the signType now support HMACSHA256</param>
        /// <param name="serviceName">the current http request request serviceName</param>
        /// <returns></returns>
        public static HttpRequestMessage DoRequestMessageSign(this HttpRequestMessage httpRequestMessage, Credential credentials,
                                                              string serviceName = null, DateTime?overWriteDate = null, JDCloudSignVersionType?signType = null)
        {
            var          headers        = httpRequestMessage.Headers;
            var          requestUri     = httpRequestMessage.RequestUri;
            var          queryString    = requestUri.Query;
            var          requestPath    = requestUri.AbsolutePath;
            var          requestContent = httpRequestMessage.Content;
            var          requestMethod  = httpRequestMessage.Method;
            string       apiVersion     = requestUri.GetRequestVersion();
            RequestModel requestModel   = new RequestModel();

            requestModel.ApiVersion = apiVersion;
            if (requestContent != null)
            {
                using (var contentStream = new MemoryStream())
                {
                    requestContent.CopyToAsync(contentStream).Wait();
                    if (contentStream.Length > 0)
                    {
                        requestModel.Content = contentStream.ToArray();
                    }
                }

                requestModel.ContentType = requestContent.Headers.ContentType.ToString();
            }
            requestModel.HttpMethod = requestMethod.ToString().ToUpper();
            var pathRegion = requestUri.GetRequestRegion();

            if (!string.IsNullOrWhiteSpace(pathRegion))
            {
                requestModel.RegionName = pathRegion;
            }
            else
            {
                requestModel.RegionName = ParameterConstant.DEFAULT_REGION;
            }

            requestModel.ResourcePath = requestPath;
            if (!string.IsNullOrWhiteSpace(serviceName))
            {
                requestModel.ServiceName = serviceName;
            }
            else
            {
                serviceName = requestUri.GetServiceName();
                if (string.IsNullOrWhiteSpace(serviceName))
                {
                    throw new Exception("service name not config , if you not use default endpoint please config service in sign");
                }
                requestModel.ServiceName = serviceName;
            }
            JDCloudSignVersionType jDCloudSignVersionType = GlobalConfig.GetInstance().SignVersionType;

            if (signType != null && signType.HasValue)
            {
                jDCloudSignVersionType = signType.Value;
            }
            requestModel.SignType        = jDCloudSignVersionType;
            requestModel.Uri             = requestUri;
            requestModel.QueryParameters = queryString;
            requestModel.OverrddenDate   = overWriteDate;

            if (!(requestUri.Scheme.ToLower() == "http" && requestUri.Port == 80) &&
                !(requestUri.Scheme.ToLower() == "https" && requestUri.Port == 443))
            {
                requestModel.RequestPort = requestUri.Port;
            }
            foreach (var headerKeyValue in headers)
            {
                requestModel.AddHeader(headerKeyValue.Key, string.Join(",", headerKeyValue.Value));
            }
            IJDCloudSigner     jDCloudSigner      = SignUtil.GetJDCloudSigner(jDCloudSignVersionType);
            SignedRequestModel signedRequestModel = jDCloudSigner.Sign(requestModel, credentials);
            var signedHeader = signedRequestModel.RequestHead;

            foreach (var key in signedHeader.Keys)
            {
                if (!httpRequestMessage.Headers.Contains(key))
                {
                    var value = signedHeader[key];
                    httpRequestMessage.Headers.TryAddWithoutValidation(key, value);
                }
            }
            return(httpRequestMessage);
        }
コード例 #7
0
        /// <summary>
        /// 进行请求签名
        /// </summary>
        /// <param name="requestModel"></param>
        /// <param name="credentials"></param>
        /// <returns></returns>
        public SignedRequestModel Sign(RequestModel requestModel, Credential credentials)
        {
            string nonceId = "";

            if (!requestModel.NonceId.IsNullOrWhiteSpace())
            {
                nonceId = requestModel.NonceId;
            }
            else if (requestModel.Header != null &&
                     requestModel.Header.Count > 0 &&
                     requestModel.Header.ContainsKey(ParameterConstant.X_JDCLOUD_NONCE))
            {
                List <string> headValues = requestModel.Header[ParameterConstant.X_JDCLOUD_NONCE];
                if (headValues != null && headValues.Count > 0)
                {
                    nonceId = headValues[0];
                }
                else
                {
                    nonceId = Guid.NewGuid().ToString().ToLower();
                }
            }
            else
            {
                nonceId = Guid.NewGuid().ToString().ToLower();
            }

            var    signDate = requestModel.OverrddenDate == null ? DateTime.Now:requestModel.OverrddenDate.Value;
            string formattedSigningDateTime = signDate.ToString(ParameterConstant.DATA_TIME_FORMAT);
            string formattedSigningDate     = signDate.ToString(ParameterConstant.HEADER_DATA_FORMAT);
            string scope         = SignUtil.GenerateScope(formattedSigningDate, requestModel.ServiceName, requestModel.RegionName, ParameterConstant.JDCLOUD_TERMINATOR);
            var    requestHeader = requestModel.Header;

            requestHeader.Add(ParameterConstant.X_JDCLOUD_DATE,
                              new List <string> {
                formattedSigningDateTime
            });
            if (!requestModel.Header.ContainsKey(ParameterConstant.X_JDCLOUD_NONCE))
            {
                requestHeader.Add(ParameterConstant.X_JDCLOUD_NONCE,
                                  new List <string> {
                    nonceId
                });
            }

            var contentSHA256 = "";

            if (requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_CONTENT_SHA256))
            {
                List <string> contentSha256Value = requestHeader[ParameterConstant.X_JDCLOUD_CONTENT_SHA256];
                if (contentSha256Value != null && contentSha256Value.Count > 0)
                {
                    contentSHA256 = contentSha256Value[0];
                }
            }
            if (contentSHA256.IsNullOrWhiteSpace())
            {
                contentSHA256 = SignUtil.CalculateContentHash(requestModel.Content);
            }
            var           requestParameters = OrderRequestParameters(requestModel.QueryParameters);
            string        path          = "";
            StringBuilder stringBuilder = new StringBuilder();

            if (!requestModel.ResourcePath.TrimStart().StartsWith("/"))
            {
                stringBuilder.Append("/");
            }
            stringBuilder.Append(requestModel.ResourcePath);
            path = stringBuilder.ToString();
            var canonicalRequest = SignUtil.CreateCanonicalRequest(requestParameters,
                                                                   GetCanonicalizedResourcePath(path, false),
                                                                   requestModel.HttpMethod.ToUpper()
                                                                   , GetCanonicalizedHeaderString(requestModel),
                                                                   GetSignedHeadersString(requestModel), contentSHA256);
            var stringToSign = SignUtil.CreateStringToSign(canonicalRequest, formattedSigningDateTime, scope, ParameterConstant.JDCLOUD2_SIGNING_ALGORITHM);

            byte[] kSecret    = System.Text.Encoding.UTF8.GetBytes($"JDCLOUD2{credentials.SecretAccessKey}");
            byte[] kDate      = SignUtil.Sign(formattedSigningDate, kSecret, ParameterConstant.SIGN_SHA256);
            byte[] kRegion    = SignUtil.Sign(requestModel.RegionName, kDate, ParameterConstant.SIGN_SHA256);
            byte[] kService   = SignUtil.Sign(requestModel.ServiceName, kRegion, ParameterConstant.SIGN_SHA256);
            byte[] signingKey = SignUtil.Sign(ParameterConstant.JDCLOUD_TERMINATOR, kService, ParameterConstant.SIGN_SHA256);
            byte[] signature  = SignUtil.ComputeSignature(stringToSign, signingKey);
            // Console.WriteLine($" kSecret={ BitConverter.ToString(kSecret).Replace("-", "")}");
            // Console.WriteLine($" kDate={ BitConverter.ToString(kDate).Replace("-", "")}");
            // Console.WriteLine($" kRegion={ BitConverter.ToString(kRegion).Replace("-", "")}");
            // Console.WriteLine($" kService={ BitConverter.ToString(kService).Replace("-", "")}");
            // Console.WriteLine($" signingKey={ BitConverter.ToString(signingKey).Replace("-", "")}");
            // Console.WriteLine($" signature={ BitConverter.ToString(signature).Replace("-", "")}");

            string signingCredentials = credentials.AccessKeyId + "/" + scope;
            string credential         = "Credential=" + signingCredentials;
            string signerHeaders      = "SignedHeaders=" + GetSignedHeadersString(requestModel);
            string signatureHeader    = "Signature=" + StringUtils.ByteToHex(signature, true);

            var signHeader = new StringBuilder().Append(ParameterConstant.JDCLOUD2_SIGNING_ALGORITHM)
                             .Append(" ")
                             .Append(credential)
                             .Append(", ")
                             .Append(signerHeaders)
                             .Append(", ")
                             .Append(signatureHeader)
                             .ToString();

            requestModel.AddHeader(ParameterConstant.AUTHORIZATION, signHeader);
            SignedRequestModel signedRequestModel = new SignedRequestModel();

            signedRequestModel.CanonicalRequest = canonicalRequest;
            signedRequestModel.ContentSHA256    = contentSHA256;
            foreach (var header in requestModel.Header)
            {
                signedRequestModel.RequestHead.Add(header.Key, string.Join(",", header.Value.ToArray()));
            }
            signedRequestModel.RequestNonceId  = nonceId;
            signedRequestModel.SignedHeaders   = signHeader;
            signedRequestModel.StringSignature = stringToSign;
            signedRequestModel.StringToSign    = stringToSign;

            return(signedRequestModel);
        }
コード例 #8
0
        /// <summary>
        /// sign with RequestModel
        /// </summary>
        /// <param name="requestModel"></param>
        /// <param name="credentials"></param>
        /// <returns></returns>
        public SignedRequestModel Sign(RequestModel requestModel, Credential credentials)
        {
            string nonceId       = "";
            var    requestHeader = ProcessRequestHeaderKeyToLower(requestModel.Header);

            if (requestModel.NonceId.IsNullOrWhiteSpace())
            {
                nonceId = Guid.NewGuid().ToString().ToLower();
            }
            else if (requestHeader != null &&
                     requestHeader.Count > 0 &&
                     requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_NONCE.ToLower()))
            {
                List <string> headValues = requestHeader[ParameterConstant.X_JDCLOUD_NONCE.ToLower()];
                if (headValues != null && headValues.Count > 0)
                {
                    nonceId = headValues[0];
                }
                else
                {
                    nonceId = Guid.NewGuid().ToString().ToLower();
                }
            }
            else
            {
                nonceId = requestModel.NonceId;
            }

            DateTime?signDate = null;

            if (requestHeader != null &&
                requestHeader.Count > 0 &&
                requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_DATE.ToLower()))
            {
                List <string> headerValues = requestHeader[ParameterConstant.X_JDCLOUD_DATE.ToLower()];
                if (headerValues != null && headerValues.Count > 0)
                {
                    string dateString = headerValues[0];
                    if (!dateString.IsNullOrWhiteSpace())
                    {
                        var tryParseDate = DateTime.Now;
                        if (DateTime.TryParseExact(dateString, ParameterConstant.DATA_TIME_FORMAT,
                                                   CultureInfo.GetCultureInfo("en-US"), System.Globalization.DateTimeStyles.None,
                                                   out tryParseDate))
                        {
                            signDate = tryParseDate;
                        }
                    }
                }
            }
            else
            {
                if (requestModel.OverrddenDate != null && requestModel.OverrddenDate.HasValue)
                {
                    signDate = requestModel.OverrddenDate.Value;
                }
            }
            if (signDate == null || !signDate.HasValue)
            {
                signDate = DateTime.UtcNow;
            }
            string formattedSigningDateTime = signDate.Value.ToString(ParameterConstant.DATA_TIME_FORMAT);
            string formattedSigningDate     = signDate.Value.ToString(ParameterConstant.HEADER_DATA_FORMAT);
            string scope = SignUtil.GenerateScope(formattedSigningDate, requestModel.ServiceName, requestModel.RegionName, ParameterConstant.JDCLOUD_TERMINATOR_V3);

            requestHeader.Add(ParameterConstant.X_JDCLOUD_DATE,
                              new List <string> {
                formattedSigningDateTime
            });
            requestHeader.Add(ParameterConstant.X_JDCLOUD_NONCE,
                              new List <string> {
                nonceId
            });
            if (requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_ALGORITHM.ToLower()))
            {
                requestHeader[ParameterConstant.X_JDCLOUD_ALGORITHM.ToLower()] = new List <string> {
                    ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3
                };
            }
            else
            {
                requestHeader.Add(ParameterConstant.X_JDCLOUD_ALGORITHM.ToLower(), new List <string> {
                    ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3
                });
            }
            var contentSHA256 = "";

            if (requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_CONTENT_SHA256))
            {
                List <string> contentSha256Value = requestHeader[ParameterConstant.X_JDCLOUD_CONTENT_SHA256];
                if (contentSha256Value != null && contentSha256Value.Count > 0)
                {
                    contentSHA256 = contentSha256Value[0];
                }
            }
            if (contentSHA256.IsNullOrWhiteSpace())
            {
                contentSHA256 = SignUtil.CalculateContentHash(requestModel.Content);
            }
            string queryParams   = ProcessQueryString(requestModel.QueryParameters);
            string requestPath   = ProcessRequestPath(requestModel.ResourcePath);
            string requestMethod = ProcessRequestMethod(requestModel.HttpMethod);
            Dictionary <string, string> processHeader = ProcessRequstHeader(ProcessRequestHeaderWithMoreValue(requestModel.Header));
            string signHeaderString    = GetSignedHeadersString(processHeader);
            string signHeaderKeyString = GetSignedHeadersKeyString(processHeader);
            var    canonicalRequest    = SignUtil.CreateCanonicalRequest(queryParams, requestPath, requestMethod, signHeaderString, signHeaderKeyString, contentSHA256);
            var    stringToSign        = SignUtil.CreateStringToSign(canonicalRequest, formattedSigningDateTime, scope, ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3);

            byte[] kSecret    = System.Text.Encoding.UTF8.GetBytes($"JDCLOUD3{credentials.SecretAccessKey}");
            byte[] kDate      = SignUtil.Sign(formattedSigningDate, kSecret, ParameterConstant.SIGN_SHA256);
            byte[] kRegion    = SignUtil.Sign(requestModel.RegionName, kDate, ParameterConstant.SIGN_SHA256);
            byte[] kService   = SignUtil.Sign(requestModel.ServiceName, kRegion, ParameterConstant.SIGN_SHA256);
            byte[] signingKey = SignUtil.Sign(ParameterConstant.JDCLOUD_TERMINATOR_V3, kService, ParameterConstant.SIGN_SHA256);
            byte[] signature  = SignUtil.ComputeSignature(stringToSign, signingKey);
            // Console.WriteLine($" kSecret={ BitConverter.ToString(kSecret).Replace("-", "")}");
            // Console.WriteLine($" kDate={ BitConverter.ToString(kDate).Replace("-", "")}");
            // Console.WriteLine($" kRegion={ BitConverter.ToString(kRegion).Replace("-", "")}");
            // Console.WriteLine($" kService={ BitConverter.ToString(kService).Replace("-", "")}");
            // Console.WriteLine($" signingKey={ BitConverter.ToString(signingKey).Replace("-", "")}");
            // Console.WriteLine($" signature={ BitConverter.ToString(signature).Replace("-", "")}");

            string signingCredentials = credentials.AccessKeyId + "/" + scope;
            string credential         = "Credential=" + signingCredentials;
            string signerHeaders      = "SignedHeaders=" + signHeaderKeyString;
            string signatureHeader    = "Signature=" + StringUtils.ByteToHex(signature, true);

            var signHeader = new StringBuilder().Append(ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3)
                             .Append(" ")
                             .Append(credential)
                             .Append(", ")
                             .Append(signerHeaders)
                             .Append(", ")
                             .Append(signatureHeader)
                             .ToString();

            requestModel.AddHeader(ParameterConstant.AUTHORIZATION, signHeader);
            SignedRequestModel signedRequestModel = new SignedRequestModel();

            signedRequestModel.CanonicalRequest = canonicalRequest;
            signedRequestModel.ContentSHA256    = contentSHA256;
            foreach (var header in requestModel.Header)
            {
                signedRequestModel.RequestHead.Add(header.Key, string.Join(",", header.Value.ToArray()));
            }
            signedRequestModel.RequestNonceId  = nonceId;
            signedRequestModel.SignedHeaders   = signHeader;
            signedRequestModel.StringSignature = stringToSign;
            signedRequestModel.StringToSign    = stringToSign;

            return(signedRequestModel);
        }