I have the following code running in a windows service:
WebClient webClient = new WebClient();
webClient.Credentials = new NetworkCredential("me", "12345", "evilcorp.com");
webClient.DownloadFile(downloadUrl, filePath);
Each time, I get the following exception
{"The remote server returned an error: (401) Unauthorized."}
With the following inner exception:
{"The function requested is not supported"}
I know for sure the credentials are valid, in fact, if I go to downloadUrl in my web browser and put in my credentials as evilcorp.com\me with password 12345, it downloads fine.
What is weird though is that if I specify my credentials as me@evilcorp.com with 12345, it appears to fail.
Is there a way to format credentials?
According to the msdn docs the exception could be because the method has been called simultaneously on multiple threads. The DownloadFile method also requires a completely qualified URL such as http://evilcorp.com/.
Apparently the OS you are running on matters, as the default encryption has changed between OSes. This blog has more details: http://ferozedaud.blogspot.com/2009/10/ntlm-auth-fails-with.html
This has apparently also been discussed on stackoverflow here: 407 Authentication required - no challenge sent
I would suggest read the blog first as the distilled knowledge is there.
webClient.UseDefaultCredentials = true;
resolved my issue.For me, 'webClient.UseDefaultCredentials = true;' solves it only on local, not in the web app on the server connecting to another server. I couldn't add the needed credential into Windows as a user, but I found later some programming way - I won't test it as I already made own solution. And also I don't want to mangle with the web server's registry, even if I have the needed admin rights. All these problems are because of the Windows internal handling of the NTLM authentication ("Windows Domain") and all of libraries and frameworks built over that (e.g. .NET).
So the solution for me was quite simple in idea - create a proxy app in a multiplatform technology with a multiplatform NTLM library where the NTLM communication is created by hand according to the public specs, not by running the built-in code in Windows. I myself chose Node.js and the httpntlm library, because it's about only one single source file with few lines and calling it from .NET as a program returning the downloaded file (also I prefer transferring it through the standard output instead of creating a temporary file).
Node.js program as a proxy to download a file behind the NTLM authentication:
.NET caller code (the web app downloading files from a web app on another server)
While writing a URL, put the '@' in front of url string.
For example:
This will solve your problem.
The answer given by P.Brian.Mackey is also correct.