protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                                      CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            var tokenCredentials = await _options.TokenCredentialProvider(request).ConfigureAwait(false);

            var queryString = QueryHelpers.ParseQuery(request.RequestUri?.Query);

            if (_options.SignedAsBody && request.Content != null && string.Equals(request.Content.Headers?.ContentType?.MediaType,
                                                                                  ApplicationFormUrlEncoded, StringComparison.OrdinalIgnoreCase))
            {
                var urlEncoded = await request.Content.ReadAsStringAsync().ConfigureAwait(false);

                var formData = QueryHelpers.ParseQuery(urlEncoded);
                foreach (var query in queryString)
                {
                    if (!formData.ContainsKey(query.Key))
                    {
                        formData.Add(query.Key, query.Value);
                    }
                }

                var parameters = _signer.AppendAuthorizationParameters(request.Method, request.RequestUri !, _options,
                                                                       formData, tokenCredentials);
                var values = new List <KeyValuePair <string?, string?> >();
                foreach (var parameter in parameters)
                {
                    if (!queryString.ContainsKey(parameter.Key))
                    {
                        values.AddRange(parameter.Value.Select(value =>
                                                               new KeyValuePair <string?, string?>(parameter.Key, value)));
                    }
                }

                // The form-encoded httpContent, see https://tools.ietf.org/html/rfc5849#section-3.5.2
                request.Content = new FormUrlEncodedContent(values);
            }
            else if (_options.SignedAsQuery)
            {
                var parameters = _signer.AppendAuthorizationParameters(request.Method, request.RequestUri !, _options,
                                                                       queryString, tokenCredentials);
                var values = new List <string>();
                foreach (var parameter in parameters)
                {
                    foreach (var value in parameter.Value)
                    {
                        values.Add($"{Uri.EscapeDataString(parameter.Key)}={Uri.EscapeDataString(value)}");
                    }
                }

                request.RequestUri = new UriBuilder(request.RequestUri !)
                {
                    Query = "?" + string.Join("&", values)
                }.Uri;
Esempio n. 2
0
        public async Task HttpClient_AccessProtectedResourceWithQueryString_ShouldAuthorized()
        {
            // Arrange
            var services = new ServiceCollection()
                           .AddOAuthHttpClient <OAuthHttpClient>((_, handlerOptions) =>
            {
                handlerOptions.ClientCredentials = new OAuthCredential(
                    _configuration["OAuth:ClientId"],
                    _configuration["OAuth:ClientSecret"]);
                handlerOptions.TokenCredentials = _tokenCredentials;
                handlerOptions.SignedAsQuery    = true;
                if (_mockHttp != null)
                {
                    var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
                                    .ToString(CultureInfo.InvariantCulture);
                    var nonce = generateNonce();
                    handlerOptions.TimestampProvider = () => timestamp;
                    handlerOptions.NonceProvider     = () => nonce;
                }
            })
                           .ConfigurePrimaryHttpMessageHandler(_ => _mockHttp ?? new HttpClientHandler() as HttpMessageHandler)
                           .Services.BuildServiceProvider();
            var client      = services.GetRequiredService <OAuthHttpClient>();
            var options     = services.GetRequiredService <IOptions <OAuthHttpHandlerOptions> >();
            var resourceUri = new UriBuilder(_configuration["Request:Uri"]);

            resourceUri.Query += resourceUri.Query.Contains('?', StringComparison.Ordinal)
                ? "&foo=v1&foo=v2"
                : "?foo=v1&foo=v2";
            var parameters = _signer.AppendAuthorizationParameters(HttpMethod.Get, resourceUri.Uri,
                                                                   options.Value, QueryHelpers.ParseQuery(resourceUri.Uri.Query), _tokenCredentials);
            var values = new List <string>();

            foreach (var parameter in parameters)
            {
                foreach (var value in parameter.Value)
                {
                    values.Add($"{Uri.EscapeDataString(parameter.Key)}={Uri.EscapeDataString(value)}");
                }
            }

            _mockHttp?.Expect(HttpMethod.Get, resourceUri.Uri.AbsoluteUri)
            .WithQueryString("?" + string.Join("&", values))
            .Respond(HttpStatusCode.OK);

            // Act
            var response = await client.HttpClient.GetAsync(resourceUri.Uri).ConfigureAwait(false);

            // Assert
            Assert.NotEqual(HttpStatusCode.Unauthorized, response.StatusCode);
            _mockHttp?.VerifyNoOutstandingExpectation();
            _mockHttp?.VerifyNoOutstandingRequest();
        }