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); } } }
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); }
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); }