I have written a WinForms app that uploads addresses from a spreadsheet, and geocodes them using an external geocoding service. This all works fine on my local machine, but the time has come for it to be installed on other peoples computers for testing. The app no longer works now though, generating the below error:
System.Net.WebException: The remote server returned an error: (407) Proxy Authentication Required.
Having read a lot and chatted breifly to our network guys, it seems i need to establish the Security Context for the users account and work with this to correct the error.
Has anyone got any pointers about how I should be going about this?
Thanks in advance!
C
It depends on how your uploading the data. If your using a http request (as it looks like you are) it will look something like;
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://test.example.com/");
req.Method = "POST";
req.ContentType = "text/xml";
req.Credentials = new NetworkCredential("TESTACCOUNT", "P#ssword");
StreamWriter writer = new StreamWriter(req.GetRequestStream());
writer.Write(input);
writer.Close();
var rsp = req.GetResponse().GetResponseStream();
Related
When establishing an https connection via HttpWebRequest in a C# application where is the list of available ciphers suites that are provided in the SSL handshake stored on the server (2008R2)? Is it a registry setting or how is this determined?
The C# code is just a simple
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(Uri);
WebReq.Method = "GET";
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
The issue I am having is that when using IE from the server the list of ciphers provided is different to what is being provided by the C# application (As captured by wireshark.) As such the C# based connection if failing as the Server supports and wants to use TLS_RSA_WITH_RC4_128_SHA which is not being provided by C# app but is being provided by browser SSL handshake.
Using the same code on other servers shows that TLS_RSA_WITH_RC4_128_SHA is being offered in the SSL handshake by the C# app so it leads me to believe that there is something environmental on that particular server but where and how this is controlled is not something I have been able to find.
I would post images of the wireshark captures to show the difference between C# application and IE SSL handshake Client Hello Cipher suite list but I have low rep points.
Here is the registry path SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers
Aright, so here's how it goes I'm trying to set a up a polling system to pull log files from several laser systems each with their own ftp. However, I'm running into difficulty when attempting to call the FtpWebResponse call to download the log file the following is the code I'm using:
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://192.168.10.140/param.dat");
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential("user", "pass");
request.UsePassive = false;
request.Proxy = null;
request.UseBinary = true;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
So I freeze up on that last line with: "The remote server returned an error: (502) Command not implemented."
I've a few different ways to grab files from the system just to see if it's some kind of setting I'm missing this is my results:
Microsoft CMD.exe: Connects up fine and can download files and perform standard ftp commands
Internet Explorer: Entering in address to file it downloads the file just fine
Firefox: "The remote server returned an error: (502) Command not implemented."
Chrome: "Error 606 (net::ERR_FTP_COMMAND_NOT_SUPPORTED): Unknown error."
Now there's not a lot of information I can get on the actual ftp set-up on the laser systems due to a long story I wont get into here but from what I'm seeing perhaps it uses some kind of legacy protocol that IE and CMD support or I'm missing something obvious. I've attempted flipping around the FtpWebRequest setting but nothing seems to work. I would really love to use this solution and not have the program auto build ftp batch files as it would really just make be sad as having everything run in program would be so much more elegant and easier to work with. Any ideas folks?
One of the things that could be causing your 502 error is attempting to use active mode when it is disabled on the server. Try using passive mode:
request.UsePassive = true
Also, from the documentation:
The URI may be relative or absolute. If the URI is of the form
"ftp://contoso.com/%2fpath" (%2f is an escaped '/'), then the URI is
absolute, and the current directory is /path. If, however, the URI is
of the form "ftp://contoso.com/path", first the .NET Framework logs
into the FTP server (using the user name and password set by the
Credentials property), then the current directory is set to
/path.
Try changing your URI to an absolute form - it may help avoid the PWD you're seeing.
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!
I have an application that needs to download several files in a row in succession (sometimes a few thousand). However, what ends up happening when several files need to be downloaded is I get an exception with an inner exception of type SocketException and the error code 10048 (WSAEADDRINUSE). I did some digging and basically it's because the server has run out of sockets (and they are all waiting for 240s or so before they become available again) - not coincidentally it starts happening around the 1024 file range. I would expect that the HttpWebRequest/ServicePointManager would be reusing my connection, but apparently it is not (and the files are https, so that may be part of it). I never saw this problem in the C++ code that this was ported from (but that doesn't mean it didn't ever happen - I'd be surprised if it was, though).
I am properly closing the WebRequest object and the HttpWebRequest object has KeepAlive set to true by default. Next my intent is to fiddle around with ServicePointManager.SetTcpKeepAlive(). However, I can't see how more people haven't run into this problem.
Has anyone else run into the problem, and if so, what did you do to get around it? Currently I have a retry scheme that detects this error and waits it out, but that doesn't seem like the right thing to do.
Here's some basic code to verify what I'm doing (just in case I'm missing closing something):
WebRequest webRequest = WebRequest.Create(uri);
webRequest.Method = "GET";
webRequest.Credentials = new NetworkCredential(username, password);
WebResponse webResponse = webRequest.GetResponse();
try
{
using(Stream stream = webResponse.GetResponseStream())
{
// read the stream
}
}
finally
{
webResponse.Close()
}
What kind of application is this? You mentioned that the server is running out of ports, but then you mentioned HttpWebRequest. Are you running this code in a webservice or ASP.NET page, which is trying to then download multiple files for the same incoming request from the client?
What kind of authentication is the page using? If it is using NTLM authentication, then the connections cannot be shared if the credentials being used are different for each request.
What I would suggest is to group your request per credential. So, for eg, all requests using username "John" would be grouped. You can specify the "ConnectionGroupName" property on the service point, so the system will try to reuse connections for the same credential and server.
If that also doesnt work, you will need to do one or more of the following:
1) Throttle your requests.
2) Increase the wildcard port range.
3) Use the BindIPConnectionCallback on ServicePoint to make it bind to a non-wildcard port (i.e a port in the range 1024-16384)
More digging seems to point to it possibly being due to authentication and the UnsafeAuthenticatedConnectionSharing property might alleviate this. However, I'm not sure that's the best thing, either.
I'm working on a .NET app that calls 3rd party web services over the internet. The services do not use SOAP, so we manually construct an XML request document, send it to the service via HTTP, and retrieve an XML response.
Our code is a Windows service that is run in the context of a normal Windows domain account, and sits behind a proxy server (Microsoft ISA Server) configured to require NTLM authentication. The account running our service has permission to access the internet through the proxy server.
The code looks like this:
// Create the request object.
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "POST";
// Configure for authenticating proxy server requiring Windows domain credentials.
request.Proxy = New WebProxy(proxyAddress) { UseDefaultCredentials = true };
// Set other required headers.
request.Accept = acceptableMimeType;
request.Headers.Add(HttpRequestHeader.AcceptCharset, acceptableCharset);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "none");
request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-gb");
request.Headers.Add(HttpRequestHeader.CacheControl, "no-store");
request.Headers.Add(HttpRequestHeader.ContentEncoding, "none");
request.Headers.Add(HttpRequestHeader.ContentLanguage, "en-gb");
request.ContentType = requestMimeType;
request.ContentLength = requestBytes.Length;
// Make the method call.
using(Stream stream = request.GetRequestStream()) {
stream.Write(requestBytes, 0, requestBytes.Length);
}
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
// Extract the data from the response without relying on the HTTP Content-Length header
// (we cannot trust all providers to set it correctly).
const int bufferSize = 1024 * 64;
List<byte> responseBytes = new List<byte>();
using(Stream stream = new BufferedStream(response.GetResponseStream(), bufferSize)) {
int value;
while((value = stream.ReadByte()) != -1) {
responseBytes.Add((byte) value);
}
}
This works fine if the proxy server is turned off, or the URL has been whitelisted as not requiring authentication, but as soon as authentication is active, it always fails with an HTTP 407 error.
I put the above code in a test harness, and tried every method I could think of for configuring the request.Proxy property, without success.
I then noticed that all the 3rd party web services that we have to call are HTTPS. When I tried accessing them as HTTP instead, the proxy authentication started working. Is there some extra hoop I have to jump through to get proxy authentication and HTTPS to play nicely?
PS: The same problems occur with the open source SmoothWall proxy server, so I can't just write it off as a bug in ISA Server.
PPS: I'm aware that you can configure proxy settings in app.config, but (a) doing it in code shouldn't make any difference, and (b) the application design requires that we read the proxy settings from a database at runtime.
Have you tried setting the proxy in the app.config ?
To disable the proxy, in the App.config file add the following configuration
<system.net>
<defaultProxy enabled="false" useDefaultCredentials="false">
<proxy/>
<bypasslist/>
<module/>
</defaultProxy>
</system.net>
To enable the proxy and to use the default proxy settings(specified in IE) add this configuration in your App.config
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy/>
<bypasslist/>
<module/>
</defaultProxy>
</system.net>
I did have a similar situation
Did you noticed it worked when you accessed the internet before you ran the code? and if you had not accessed the internet for ages (20mins for me) you got the error.
have you tried to set the proxy credentials directly?
//setup the proxy
request.Proxy = new WebProxy("proxyIp", 8080);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
I hope this fixes your issue too
I think I will have to write off this question. My original posted code does appear to work sometimes. Our proxy server is extremely unreliable; one minute it will block an internet connection from any software, and the next it will allow it. The IT guys seem powerless to do anything about it, and we (everyone outside the IT department) have no authority to make changes to the network infrastructure.
If anyone has any ideas on how to "harden" my code to compensate for an unreliable proxy server, then I'd be interested to hear them. :-)
Is there something wrong with your proxy server's certificate? If your service can't establish HTTPS then it will throw an error.