/// <summary>This is the main code to sign a request.</summary>
        /// <param name="requestMessage">An HttpRequestMessage to be signed.</param>
        public void SignRequest(HttpRequestMessage requestMessage)
        {
            HttpMethod         httpMethod       = requestMessage.Method;
            HttpRequestHeaders httpHeaders      = requestMessage.Headers;
            HttpContent        body             = requestMessage.Content;
            string             requestMethodKey = httpMethod.Method.ToLowerInvariant();

            // Verify if the http request Method is supported.
            if (!signingStrategy.RequiredHeaders.TryGetValue(requestMethodKey, out var requiredHeaders))
            {
                throw new ArgumentException($"Http Request Method not found: {requestMethodKey}");
            }

            var headersToSign = requiredHeaders.ToList();

            // Add any missing required headers.
            SigningUtils.AddMissingHeaders(requestMessage, headersToSign);

            // Calculate the Signing string.
            var signingString = SigningUtils.CalculateStringToSign(requestMessage, headersToSign);

            logger.Debug($"signing string is {signingString}");

            var bytes = Encoding.UTF8.GetBytes(signingString);

            this.signer.BlockUpdate(bytes, 0, bytes.Length);
            var signature = Convert.ToBase64String(this.signer.GenerateSignature());

            var authorization = SigningUtils.CalculateAuthorization(headersToSign, SIGNATURE_VERSION, this.keyId, SIGNATURE_ALGORITHM, signature);

            httpHeaders.Add(Constants.AUTHORIZATION_HEADER, authorization);
        }
Esempio n. 2
0
        /// <summary>This is the main code to sign a request.</summary>
        /// <param name="requestMessage">An HttpRequestMessage to be signed.</param>
        public override void SignRequest(HttpRequestMessage requestMessage)
        {
            HttpMethod         httpMethod       = requestMessage.Method;
            HttpRequestHeaders httpHeaders      = requestMessage.Headers;
            HttpContent        body             = requestMessage.Content;
            string             requestMethodKey = httpMethod.Method.ToLowerInvariant();

            // Verify if the http request Method is supported.
            if (!signingStrategy.RequiredHeaders.TryGetValue(requestMethodKey, out var requiredHeaders))
            {
                throw new ArgumentException($"Http Request Method not found: {requestMethodKey}");
            }

            var headersToSign = requiredHeaders.ToList();
            //Add the Instance OBO User delegation token to request headers if the auth details provider implements IUserDelegationDetailsProvider and
            //if a token is available.
            var delegationToken = (AuthDetailsProvider as IUserDelegationDetailsProvider)?.GetDelegationToken();

            if (delegationToken != null)
            {
                logger.Debug($"Adding {Constants.OPC_OBO_TOKEN} to request headers");
                requestMessage.Headers.TryAddWithoutValidation(Constants.OPC_OBO_TOKEN, delegationToken);
            }

            // For PUT and POST, if the body is empty we still must explicitly set content-length = 0 and x-content-sha256.
            // The caller may already do this, but we shouldn't require it since we can determine it here.
            if (body == null && (string.Equals(requestMethodKey, "post") || string.Equals(requestMethodKey, "put")))
            {
                requestMessage.Content = new StringContent("");
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                requestMessage.Content.Headers.TryAddWithoutValidation(Constants.CONTENT_LENGTH, "0");
                requestMessage.Content.Headers.TryAddWithoutValidation(Constants.X_CONTENT_SHA256, Convert.ToBase64String(SHA256.Create().ComputeHash(new byte[0])));
            }

            // Few requests accept Constants.OPTIONAL_HEADERS_NAMES headers. In such cases, if the request contains any of the optional headers,
            // we need to include them in request signature.
            if (signingStrategy.OptionalHeaders.TryGetValue(requestMethodKey, out var optionalHeaders))
            {
                foreach (var optionalHeaderName in optionalHeaders)
                {
                    if (httpHeaders.Contains(optionalHeaderName))
                    {
                        headersToSign.Add(optionalHeaderName);
                    }
                }
            }

            // Add any missing required headers.
            SigningUtils.AddMissingHeaders(requestMessage, headersToSign);

            // Calculate the Signing string.
            var signingString = SigningUtils.CalculateStringToSign(requestMessage, headersToSign);
            var bytes         = Encoding.UTF8.GetBytes(signingString);

            this.signer.BlockUpdate(bytes, 0, bytes.Length);
            var signature = Convert.ToBase64String(this.signer.GenerateSignature());

            var authorization = SigningUtils.CalculateAuthorization(headersToSign, SIGNATURE_VERSION, this.keyId, SIGNATURE_ALGORITHM, signature);

            httpHeaders.Add(Constants.AUTHORIZATION_HEADER, authorization);
        }