private static SortedDictionary <string, string> GetHeadersToSign( IDictionary <string, string> headers, HashSet <string> headersToSign) { var ret = new SortedDictionary <string, string>(); if (headersToSign != null) { var tempSet = new HashSet <string>(); foreach (string header in headersToSign) { tempSet.Add(header.Trim().ToLower()); } headersToSign = tempSet; } foreach (KeyValuePair <string, string> entry in headers) { string key = entry.Key; if (!string.IsNullOrEmpty(entry.Value)) { if ((headersToSign == null && BceV1Signer.IsDefaultHeaderToSign(key)) || (headersToSign != null && headersToSign.Contains(key.ToLower()) && !BceConstants.HttpHeaders.Authorization.Equals(key, StringComparison.OrdinalIgnoreCase))) { ret.Add(key, entry.Value); } } } return(ret); }
/// <summary> /// Sign the given request. Modifies the passed-in request to apply the signature. /// </summary> /// <param name="request"> the request to sign. </param> public string Sign(InternalRequest request) { if (request == null) { throw new ArgumentNullException("request should NOT be null."); } var config = request.Config; if (config == null) { throw new ArgumentNullException("request.Config should NOT be null."); } var credentials = config.Credentials; if (credentials == null) { throw new ArgumentNullException("request.Config.Credentials should NOT be null."); } var options = request.Config.SignOptions; if (options == null) { options = new SignOptions(); } string accessKeyId = credentials.AccessKeyId; string secretAccessKey = credentials.SecretKey; var timestamp = options.Timestamp; if (timestamp == DateTime.MinValue) { timestamp = DateTime.Now; } string authString = BceAuthVersion + "/" + accessKeyId + "/" + DateUtils.FormatAlternateIso8601Date(timestamp) + "/" + options.ExpirationInSeconds; string signingKey = BceV1Signer.Sha256Hex(secretAccessKey, authString); // Formatting the URL with signing protocol. string canonicalURI = BceV1Signer.GetCanonicalURIPath(HttpUtility.UrlDecode(request.Uri.AbsolutePath)); // Formatting the query string with signing protocol. string canonicalQueryString = HttpUtils.GetCanonicalQueryString(request.Parameters, true); // Sorted the headers should be signed from the request. SortedDictionary <string, string> headersToSign = BceV1Signer.GetHeadersToSign(request.Headers, options.HeadersToSign); // Formatting the headers from the request based on signing protocol. string canonicalHeader = BceV1Signer.GetCanonicalHeaders(headersToSign); string signedHeaders = ""; if (options.HeadersToSign != null) { signedHeaders = string.Join(";", headersToSign.Keys.ToArray()).Trim().ToLower(); } string canonicalRequest = request.HttpMethod + "\n" + canonicalURI + "\n" + canonicalQueryString + "\n" + canonicalHeader; // Signing the canonical request using key with sha-256 algorithm. string signature = BceV1Signer.Sha256Hex(signingKey, canonicalRequest); string authorizationHeader = authString + "/" + signedHeaders + "/" + signature; log.Debug(string.Format( "CanonicalRequest:{0}\tAuthorization:{1}", canonicalRequest.Replace("\n", "[\\n]"), authorizationHeader)); return(authorizationHeader); }