Accessing Gitlab Api with HttpWebRequest in C# - c#

I am trying to access my the API on my Gitlab server. It works with curl but not from my C# code.
curl --insecure https://gitlab.mycompany.de/dev/TestProjekt/milestones -H "Accept: application/json" -H "Private-Token: my_token"
ServicePointManager.ServerCertificateValidationCallback = (obj, certificate, chain, errors) => (true);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var req = WebRequest.CreateHttp(new Uri("https://gitlab.mycompany.de/dev/TestProjekt/milestones"));
req.Headers.Add("Private-Token", "my_token");
req.Accept = "application/json";
req.Method = "GET";
var res = req.GetResponse();
My C# code causes an WebException with the message "underlying connection was closed an unexpected error occurred on a send" (i got german error message, but i am convinced that this is the correct translation)
In my opinion both requests should send the same data. I tried sending requests to http instead of https to see the packages in wireshark. Curl sends an additional header "user agent" and c# sends "Connection: Keep Alive". Adding a user agent to the C# request won't help either.
Does anyone have an idea what might be different?

After Cleaning and Rebuilding everthing multiple times, I now get the expected answers.

Related

The request was aborted: Could not create SSL/TLS secure channel - Tried all possible solution

I'm facing an issue once I want to call HttpWebRequest and the error says: The request was aborted: Could not create SSL/TLS secure channel
The code is as below for HttpWebRequest, and it is working without errors in my workstation [ working without SecurityProtocol code ]
var request = HttpWebRequest.Create("https://www.xxTestxx.com");
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = 0;
request.Headers.Add("x-api-key", "TESTXXXXAPI");
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Got error message: The request was aborted: Could not create SSL/TLS secure channel.
(Above code was a working fine before a few days on the staging server)
Then I added below two lines to the code, after we deploy it again, still it's giving same error message:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
None of the above code is working, and we got an error: The request was aborted: Could not create SSL/TLS secure channel
Kindly note I tried the below also:
ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
Last I tried disabling SSL 3.0 for the IIS server on a staging server, I changed the values in registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
Added the new SSL 3.0 key as below:
Client:
DisabledByDefault 1
Server:
Enabled 0
Please help same code was working fine before a few days, I don't know if I need to add extra code, or if the error showed up related to the configuration from the server?

HTTPS over proxy doesn't work

I'm aware that there are tons of questions and answers on StackOverflow and all over the internet with exactly the same or very similar error message and I'm pretty sure I've read and tried 90% of them. I still can't get this fixed.
Below is the code with WebClient, as suggested by Visual Studio. But I also tried with HttpWebRequest/WebRequest, despite the warning that it's obsolete. No change, I got the same error: "The request was aborted: Could not create SSL/TLS secure channel.".
Now here's the code. makeProxy is really just 3 lines, a new WebProxy plus the credentials for it. I believe it works because (a) if I provide a wrong credential there then I get an authentication error, (b) if I try to go to a http and not a https page, then I get it back, so I'm out on the internet.
protected string getToken() {
string url = ConfigurationManager.AppSettings["domo_api_url_auth"];
WebClient c = new WebClient();
c.Proxy = makeProxy();
c.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["domo_api_cid"], ConfigurationManager.AppSettings["domo_api_pwd"]);
c.Encoding = System.Text.Encoding.UTF8;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
// ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
// ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
Stream responseStream = c.OpenRead(url);
return new StreamReader(responseStream).ReadToEnd();
}
My problem is that the message is not very helpful. I also tried to debug it, didn't help. I thought of the certificate on the site of the web service I'm trying to reach and went through the process of allowing that cert for W3SVC. Didn't help. And I get this same error for every https site, like google.com or stackoverflow.com or my own company's web site. But when I go to a random news site with http only, everything works fine.
The extremely suspicious thing is that it doesn't work even when I uncomment that first ServerCertificateValidationCallback line, and when I uncomment the second, supposedly redirecting the code to the validation, it literally never gets there. Like the validation wouldn't even start.
How to troubleshoot this? I don't even understand on which point of the web request-response process it fails.
You likely need to activate TLS in addition to SSLv3:
ServicePointManager.SecurityProtocol =
SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;

Sending an HttpWebRequest to an HTTPS REST service

I'm trying to send a JSON request to a REST service that is HTTPS secured. The client explained that the REST service is using self-signed certificates. He also explained that this is a development service and that I should ignore any certificate warnings. (The service is running on a RaspberryPi in our office)
He forwarded me the following CURL request to demonstrate that it's working:
curl -k -H "Content-Type: application/json" -X POST -d '{"MerchantReference":"[removed]",
"Command":"Debit", "Amount":5500,"DeviceSerialNumber":"[removed]"}' https://[removed]
When I establish a connection with Putty and run this, I get a response so all is good. But when I write an app in C# to do this, I get the following exception:
"The underlying connection was closed: An unexpected error occurred on a send." The inner exception is: "Authentication failed because the remote party has closed the transport stream."
Here is my C# code:
var tempRequest = #"{""MerchantReference"":""[removed]"",""Command"":""Debit"",
""Amount"":5500,""DeviceSerialNumber"":""[removed]""}";
HttpWebRequest webRequest = WebRequest.Create(HttpAddress) as HttpWebRequest;
webRequest.Method = WebRequestMethods.Http.Post;
webRequest.ContentType = "application/json";
byte[] buffer = Encoding.UTF8.GetBytes(tempRequest);
Stream postData = webRequest.GetRequestStream();
postData.Write(buffer, 0, buffer.Length);
postData.Close();
var webResponse = webRequest.GetResponse(); // The exception occurred here
I have added a callback to ServicePointManager.ServerCertificateValidationCallback at the start of the application to just accept any certificate but the execution doesn't even reach that part.
So my question would be how to replicate the CURL result in C#.
Any assistance would be greatly appreciated.
I've found the problem. TLS v1.2 is used and we are using .Net 4.0 which only supports up to TLS V1.0. We'll either upgrade to .Net 4.5 or use a different version of TLS.

WCF Error 401 Unauthorized only on some pcs

I have a WinForms app that calls a WCF service hosted on IIS7. For some reason, computers attached to the client network get a 401 Unauthorized error when trying to connect to the WCF Service through the WinForms app. I have spent quite a bit of time trying to figure this out and this is what I have found out so far.
The WinForms app receives the WCF service data on any other PC not on the client network.
From the client network, I can browse to the WCF service through a web browser just fine.
From the client network, I can browse to a service method and get the "Method not allowed"
error as expected.
Also, it should be noted that the WCF service is using REST instead of SOAP.
Here is the code I use to do all the service calls:
byte[] dataStream = Encoding.UTF8.GetBytes(strParameters);
WebRequest webRequest = WebRequest.Create(strUrl + strFunction);
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.ContentLength = dataStream.Length;
Stream newStream = webRequest.GetRequestStream();
newStream.Write(dataStream, 0, dataStream.Length);
newStream.Close();
WebResponse response = webRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
string responseString = responseReader.ReadToEnd();
Does anyone have any clues as to why I would be getting the 401 error only on the Client's network?
My suggestion would be to try the call via fiddler from the clients machine and validate if you can get the expected result via a POST. If this is successful I would look into how you are hosting the service in IIS. I have seen on several occasions where the issue was Anonymous or Basic Authentication was turned off which caused similar issues.

HTTPWebRequest.GetResponse() failing with authenticated requests through a transparent proxy

We're using the HTTPWebRequest objects to make HTTP requests to our application and we're having a problem when the request requires authentication and there is a transparent proxy (Squid 3.1.10).
string url = "http://www.icode.co.uk/test/auth.php";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
MessageBox.Show(reader.ReadToEnd());
reader.Close();
stream.Close();
response.Close();
Our original code used the WebClient class which exhibited the same problem.
The first time this code runs, it displays the result correctly.
When the code runs a second time, it fails on the GetResponse() line with:
System.Net.WebException was unhandled
Message="The server committed a protocol violation. Section=ResponseStatusLine"
Source="System"
StackTrace:
at System.Net.HttpWebRequest.GetResponse()
at Dummy.DummyForm.button1_Click(Object sender, EventArgs e) in H:\Trial\Dummy\DummyForm.cs:line 42
at ...
On Windows 7, restarting the process causes it to recover and work once, but Server 2003 requires a full reboot.
Looking at the network capture, two requests are identical to start with, the initial unauthenticated request is sent and the server replies, but the failing requests sends the 2nd authenticated request in the middle of the initial reply as if it's ignoring the Content-Length header (which is correct). It then receives the rest of the initial reply and fails with the protocol error.
It does seem odd that the client (HTTPWebRequest) doesn't close the connection cleanly though.
When the proxy is not in use (non port 80 or internal traffic) the requests all work as expected. When there is no authentication, it also works as it only makes the single request.
I've already reduced the problem code to the minimum and reproduced it with the MSDN sample, but does anyone know if this is a known issue or a problem in our (.NET or Squid) configuration?
Since it only fails the second time, would
request.KeepAlive = false;
make a difference?
I think NTLM authentication (NetworkCredential) does not work at the same time with transparent proxy feature of SQUID. :-(
http://www.squid-cache.org/mail-archive/squid-users/201110/0025.html
Could you try another authentication scheme?
Try authenticating yourself, with
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));
before the request.GetResponse();
This worked for me. First I tried putting in the whole string myself, which didn't work!

Categories

Resources