コード例 #1
0
        /// <summary>
        /// Gets the Headers for HttpSigning
        /// </summary>
        /// <param name="method"></param>
        /// <param name="path"></param>
        /// <param name="requestOptions"></param>
        /// <returns></returns>
        internal Dictionary <string, string> GetHttpSignedHeader(string basePath, string method, string path, RequestOptions requestOptions)
        {
            const string HEADER_REQUEST_TARGET = "(request-target)";
            //The time when the HTTP signature expires. The API server should reject HTTP requests
            //that have expired.
            const string HEADER_EXPIRES = "(expires)";
            //The 'Date' header.
            const string HEADER_DATE = "Date";
            //The 'Host' header.
            const string HEADER_HOST = "Host";
            //The time when the HTTP signature was generated.
            const string HEADER_CREATED = "(created)";
            //When the 'Digest' header is included in the HTTP signature, the client automatically
            //computes the digest of the HTTP request body, per RFC 3230.
            const string HEADER_DIGEST = "Digest";
            //The 'Authorization' header is automatically generated by the client. It includes
            //the list of signed headers and a base64-encoded signature.
            const string HEADER_AUTHORIZATION = "Authorization";

            //Hash table to store singed headers
            var HttpSignedRequestHeader = new Dictionary <string, string>();
            var HttpSignatureHeader     = new Dictionary <string, string>();

            if (HttpSigningHeader.Count == 0)
            {
                HttpSigningHeader.Add("(created)");
            }

            if (requestOptions.PathParameters != null)
            {
                foreach (var pathParam in requestOptions.PathParameters)
                {
                    var tempPath = path.Replace(pathParam.Key, "0");
                    path = string.Format(tempPath, pathParam.Value);
                }
            }

            var httpValues = HttpUtility.ParseQueryString(String.Empty);

            foreach (var parameter in requestOptions.QueryParameters)
            {
                if (parameter.Value.Count > 1)
                { // array
                    foreach (var value in parameter.Value)
                    {
                        httpValues.Add(parameter.Key + "[]", value);
                    }
                }
                else
                {
                    httpValues.Add(parameter.Key, parameter.Value[0]);
                }
            }
            var uriBuilder = new UriBuilder(string.Concat(basePath, path));

            uriBuilder.Query = httpValues.ToString();

            var    dateTime = DateTime.Now;
            String Digest   = String.Empty;

            //get the body
            string requestBody = string.Empty;

            if (requestOptions.Data != null)
            {
                var serializerSettings = new JsonSerializerSettings();
                serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                requestBody = JsonConvert.SerializeObject(requestOptions.Data, serializerSettings);
            }

            if (HashAlgorithm == HashAlgorithmName.SHA256)
            {
                var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
                Digest = string.Format("SHA-256={0}", Convert.ToBase64String(bodyDigest));
            }
            else if (HashAlgorithm == HashAlgorithmName.SHA512)
            {
                var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
                Digest = string.Format("SHA-512={0}", Convert.ToBase64String(bodyDigest));
            }
            else
            {
                throw new Exception(string.Format("{0} not supported", HashAlgorithm));
            }


            foreach (var header in HttpSigningHeader)
            {
                if (header.Equals(HEADER_REQUEST_TARGET))
                {
                    var targetUrl = string.Format("{0} {1}{2}", method.ToLower(), uriBuilder.Path, uriBuilder.Query);
                    HttpSignatureHeader.Add(header.ToLower(), targetUrl);
                }
                else if (header.Equals(HEADER_EXPIRES))
                {
                    var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
                    HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
                }
                else if (header.Equals(HEADER_DATE))
                {
                    var utcDateTime = dateTime.ToString("r").ToString();
                    HttpSignatureHeader.Add(header.ToLower(), utcDateTime);
                    HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
                }
                else if (header.Equals(HEADER_HOST))
                {
                    HttpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
                    HttpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
                }
                else if (header.Equals(HEADER_CREATED))
                {
                    HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
                }
                else if (header.Equals(HEADER_DIGEST))
                {
                    HttpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
                    HttpSignatureHeader.Add(header.ToLower(), Digest);
                }
                else
                {
                    bool isHeaderFound = false;
                    foreach (var item in requestOptions.HeaderParameters)
                    {
                        if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
                        {
                            HttpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
                            isHeaderFound = true;
                            break;
                        }
                    }
                    if (!isHeaderFound)
                    {
                        throw new Exception(string.Format("Cannot sign HTTP request.Request does not contain the {0} header.", header));
                    }
                }
            }
            var headersKeysString = String.Join(" ", HttpSignatureHeader.Keys);
            var headerValuesList  = new List <string>();

            foreach (var keyVal in HttpSignatureHeader)
            {
                headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
            }
            //Concatinate headers value separated by new line
            var    headerValuesString  = string.Join("\n", headerValuesList);
            var    signatureStringHash = GetStringHash(HashAlgorithm.ToString(), headerValuesString);
            string headerSignatureStr  = null;
            var    keyType             = GetKeyType(KeyFilePath);

            if (keyType == PrivateKeyType.RSA)
            {
                headerSignatureStr = GetRSASignature(signatureStringHash);
            }
            else if (keyType == PrivateKeyType.ECDSA)
            {
                headerSignatureStr = GetECDSASignature(signatureStringHash);
            }
            var cryptographicScheme      = "hs2019";
            var authorizationHeaderValue = string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\"",
                                                         KeyId, cryptographicScheme);


            if (HttpSignatureHeader.ContainsKey(HEADER_CREATED))
            {
                authorizationHeaderValue += string.Format(",created={0}", HttpSignatureHeader[HEADER_CREATED]);
            }

            if (HttpSignatureHeader.ContainsKey(HEADER_EXPIRES))
            {
                authorizationHeaderValue += string.Format(",expires={0}", HttpSignatureHeader[HEADER_EXPIRES]);
            }

            authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"",
                                                      headersKeysString, headerSignatureStr);

            HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);

            return(HttpSignedRequestHeader);
        }
コード例 #2
0
        internal Dictionary <string, string> GetHttpSignedHeader(System.Net.Http.HttpRequestMessage request, string requestBody, System.Threading.CancellationToken?cancellationToken = null)
        {
            if (request.RequestUri == null)
            {
                throw new NullReferenceException("The request URI was null");
            }

            const string HEADER_REQUEST_TARGET = "(request-target)";

            // The time when the HTTP signature expires. The API server should reject HTTP requests that have expired.
            const string HEADER_EXPIRES = "(expires)";

            //The 'Date' header.
            const string HEADER_DATE = "Date";

            //The 'Host' header.
            const string HEADER_HOST = "Host";

            //The time when the HTTP signature was generated.
            const string HEADER_CREATED = "(created)";

            //When the 'Digest' header is included in the HTTP signature, the client automatically
            //computes the digest of the HTTP request body, per RFC 3230.
            const string HEADER_DIGEST = "Digest";

            //The 'Authorization' header is automatically generated by the client. It includes
            //the list of signed headers and a base64-encoded signature.
            const string HEADER_AUTHORIZATION = "Authorization";

            //Hash table to store singed headers
            var HttpSignedRequestHeader = new Dictionary <string, string>();

            var httpSignatureHeader = new Dictionary <string, string?>();

            if (HttpSigningHeader.Count == 0)
            {
                HttpSigningHeader.Add("(created)");
            }

            var    dateTime = DateTime.Now;
            string digest   = String.Empty;

            if (HashAlgorithm == HashAlgorithmName.SHA256)
            {
                var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
                digest = string.Format("SHA-256={0}", Convert.ToBase64String(bodyDigest));
            }
            else if (HashAlgorithm == HashAlgorithmName.SHA512)
            {
                var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
                digest = string.Format("SHA-512={0}", Convert.ToBase64String(bodyDigest));
            }
            else
            {
                throw new Exception(string.Format("{0} not supported", HashAlgorithm));
            }

            foreach (var header in HttpSigningHeader)
            {
                if (header.Equals(HEADER_REQUEST_TARGET))
                {
                    httpSignatureHeader.Add(header.ToLower(), request.RequestUri.ToString());
                }
                else if (header.Equals(HEADER_EXPIRES))
                {
                    var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
                    httpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
                }
                else if (header.Equals(HEADER_DATE))
                {
                    var utcDateTime = dateTime.ToString("r").ToString();
                    httpSignatureHeader.Add(header.ToLower(), utcDateTime);
                    HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
                }
                else if (header.Equals(HEADER_HOST))
                {
                    httpSignatureHeader.Add(header.ToLower(), request.RequestUri.ToString());
                    HttpSignedRequestHeader.Add(HEADER_HOST, request.RequestUri.ToString());
                }
                else if (header.Equals(HEADER_CREATED))
                {
                    httpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
                }
                else if (header.Equals(HEADER_DIGEST))
                {
                    HttpSignedRequestHeader.Add(HEADER_DIGEST, digest);
                    httpSignatureHeader.Add(header.ToLower(), digest);
                }
                else
                {
                    bool isHeaderFound = false;
                    foreach (var item in request.Headers)
                    {
                        if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
                        {
                            httpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
                            isHeaderFound = true;
                            break;
                        }
                    }

                    if (!isHeaderFound)
                    {
                        throw new Exception(string.Format("Cannot sign HTTP request.Request does not contain the {0} header.", header));
                    }
                }
            }

            var headersKeysString = String.Join(" ", httpSignatureHeader.Keys);
            var headerValuesList  = new List <string>();

            foreach (var keyVal in httpSignatureHeader)
            {
                headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
            }

            //Concatinate headers value separated by new line
            var    headerValuesString  = string.Join("\n", headerValuesList);
            var    signatureStringHash = GetStringHash(HashAlgorithm.ToString(), headerValuesString);
            string?headerSignatureStr  = null;
            var    keyType             = GetKeyType(KeyFilePath);

            if (keyType == PrivateKeyType.RSA)
            {
                headerSignatureStr = GetRSASignature(signatureStringHash);
            }

            else if (keyType == PrivateKeyType.ECDSA)
            {
                headerSignatureStr = GetECDSASignature(signatureStringHash);
            }

            var cryptographicScheme      = "hs2019";
            var authorizationHeaderValue = string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\"",
                                                         KeyId, cryptographicScheme);

            if (httpSignatureHeader.ContainsKey(HEADER_CREATED))
            {
                authorizationHeaderValue += string.Format(",created={0}", httpSignatureHeader[HEADER_CREATED]);
            }

            if (httpSignatureHeader.ContainsKey(HEADER_EXPIRES))
            {
                authorizationHeaderValue += string.Format(",expires={0}", httpSignatureHeader[HEADER_EXPIRES]);
            }

            authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"", headersKeysString, headerSignatureStr);

            HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);

            return(HttpSignedRequestHeader);
        }