Search code examples
c#curlpostmanhttpclientkeycloak

Web Request - The underlying connection was closed: The connection was closed unexpectedly


When I run the following command in Curl, I get a correct and expected result:

curl -d "client_secret=VALUE" -d "client_id=VALUE" -d "username=VALUE" -d "password=VALUE" -d "grant_type=VALUE" "https://<host>/auth/realms/test-rai/protocol/openid-connect/token"

(When the same request is fired with Postman, the result is also correct.)

However, when I fire the (same) request from C#, I run into an exception:

using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace HttpClientPost
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var url = "https://<host>/auth/realms/test-rai/protocol/openid-connect/token";

            var values = new List<KeyValuePair<string, string>>()
            {
                new KeyValuePair<string, string>("client_secret", "VALUE"),
                new KeyValuePair<string, string>("client_id", "VALUE"),
                new KeyValuePair<string, string>("username", "VALUE"),
                new KeyValuePair<string, string>("password", "VALUE"),
                new KeyValuePair<string, string>("grant_type", "VALUE")
            };

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
                                                   SecurityProtocolType.Tls11 |
                                                   SecurityProtocolType.Tls12 |
                                                   SecurityProtocolType.Ssl3;

            using (var httpClient = new HttpClient())
            {
                using (var content = new FormUrlEncodedContent(values))
                {
                    content.Headers.Clear();
                    content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

                    // Throws exception: An error occurred while sending the request. The underlying connection was closed: The connection was closed unexpectedly.
                    HttpResponseMessage response = await httpClient.PostAsync(url, content);

                    var result = await response.Content.ReadAsStringAsync();
                }
            }
        }
    }
}

The thrown exception is:

An error occurred while sending the request. The underlying connection was closed: The connection was closed unexpectedly.

While searching the web, I found a lot of references for setting the 'ServicePointManager.SecurityProtocol', which I did. (Tested all options.)

Since both Curl and Postman are giving the correct/expected result: What am I missing here?


Solution

  • I found the answer myself:

    Since my request was working as expected within Postman as well as Curl, I noticed an option in Postman to convert a Postman request into a specific language: Underneath the 'Save' button, you'll find a 'Code' button to achieve this.

    My generated - and working well - C# code was:

    static void Main(string[] args)
    {
        var client = new RestClient("https://<host>/auth/realms/test-rai/protocol/openid-connect/token");
        client.Timeout = -1;
        var request = new RestRequest(Method.POST);
        request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
        request.AddParameter("grant_type", "password");
        request.AddParameter("client_id", "VALUE");
        request.AddParameter("username", "VALUE");
        request.AddParameter("password", "VALUE");
        request.AddParameter("client_secret", "VALUE");
        IRestResponse response = client.Execute(request);
        Console.WriteLine(response.Content);
    }