private static IEnumerable <string> FilterHeaders(IReadOnlyDictionary <string, string> headers)
        {
            foreach (string key in headers.Select(x => x.Key).OrderBy(x => x, StringComparer.OrdinalIgnoreCase))
            {
                string loweredKey = key.ToLowerInvariant();

                if (SigningConstants.ShouldSignHeader(loweredKey))
                {
                    yield return(loweredKey);
                }
            }
        }
Пример #2
0
        public string SignRequest <TReq>(TReq request, TimeSpan expiresIn) where TReq : IRequest
        {
            request.Timestamp = DateTimeOffset.UtcNow;
            request.RequestId = Guid.NewGuid();

            _logger.LogTrace("Handling {RequestType} with request id {RequestId}", typeof(TReq).Name, request.RequestId);

            S3Config config = _options.Value;

            _marshaller.MarshalRequest(request, config);

            _validator.ValidateAndThrow(request);

            StringBuilder sb = StringBuilderPool.Shared.Rent(200);

            RequestHelper.AppendScheme(sb, config);
            int schemeLength = sb.Length;

            RequestHelper.AppendHost(sb, config, request);

            request.SetHeader(HttpHeaders.Host, sb.ToString(schemeLength, sb.Length - schemeLength));

            string scope = _scopeBuilder.CreateScope("s3", request.Timestamp);

            request.SetQueryParameter(AmzParameters.XAmzAlgorithm, SigningConstants.AlgorithmTag);
            request.SetQueryParameter(AmzParameters.XAmzCredential, _options.Value.Credentials.KeyId + '/' + scope);
            request.SetQueryParameter(AmzParameters.XAmzDate, request.Timestamp.ToString(DateTimeFormats.Iso8601DateTime, DateTimeFormatInfo.InvariantInfo));
            request.SetQueryParameter(AmzParameters.XAmzExpires, expiresIn.TotalSeconds.ToString(NumberFormatInfo.InvariantInfo));
            request.SetQueryParameter(AmzParameters.XAmzSignedHeaders, string.Join(";", SigningConstants.FilterHeaders(request.Headers).Select(x => x.Key)));

            //Copy all headers to query parameters
            foreach (KeyValuePair <string, string> header in request.Headers)
            {
                if (header.Key == HttpHeaders.Host)
                {
                    continue;
                }

                request.SetQueryParameter(header.Key, header.Value);
            }

            _authBuilder.BuildAuthorization(request);

            //Clear sensitive material from the request
            if (request is IContainSensitiveMaterial sensitive)
            {
                sensitive.ClearSensitiveMaterial();
            }

            RequestHelper.AppendUrl(sb, config, request);
            RequestHelper.AppendQueryParameters(sb, request);

            string url = sb.ToString();

            StringBuilderPool.Shared.Return(sb);
            return(url);
        }
Пример #3
0
        internal string BuildInternal(DateTimeOffset date, IReadOnlyDictionary <string, string> headers, byte[] signature)
        {
            _logger.LogTrace("Building header based authorization");

            string scope = _scopeBuilder.CreateScope("s3", date);

            StringBuilder header = StringBuilderPool.Shared.Rent(250);

            header.Append(SigningConstants.AlgorithmTag);
            header.AppendFormat(CultureInfo.InvariantCulture, " Credential={0}/{1},", _options.Value.Credentials.KeyId, scope);
            header.AppendFormat(CultureInfo.InvariantCulture, "SignedHeaders={0},", string.Join(";", SigningConstants.FilterHeaders(headers).Select(x => x.Key)));
            header.AppendFormat(CultureInfo.InvariantCulture, "Signature={0}", signature.HexEncode());

            string authHeader = header.ToString();

            StringBuilderPool.Shared.Return(header);
            _logger.LogDebug("AuthHeader: {AuthHeader}", authHeader);
            return(authHeader);
        }