views:

2249

answers:

4

I am trying to use System.Net.WebClient in a WinForms application to upload a file to an IIS6 server which has Windows Authentication as it only 'Authentication' method.

WebClient myWebClient = new WebClient();
myWebClient.Credentials = new System.Net.NetworkCredential(@"boxname\peter", "mypassword"); 
byte[] responseArray = myWebClient.UploadFile("http://localhost/upload.aspx", fileName);

I get a 'The remote server returned an error: (401) Unauthorized', actually it is a 401.2

Both client and IIS are on the same Windows Server 2003 Dev machine.

When I try to open the page in Firefox and enter the same correct credentials as in the code, the page comes up. However when using IE8, I get the same 401.2 error.

Tried Chrome and Opera and they both work.

I have 'Enable Integrated Windows Authentication' enabled in the IE Internet options.

The Security Event Log has a Failure Audit:

Logon Failure:
    Reason:  An error occurred during logon
    User Name: peter
    Domain:  boxname
    Logon Type: 3
    Logon Process: ÈùÄ
    Authentication Package: NTLM
    Workstation Name: boxname
    Status code: 0xC000006D
    Substatus code: 0x0
    Caller User Name: -
    Caller Domain: -
    Caller Logon ID: -
    Caller Process ID: -
    Transited Services: -
    Source Network Address: 127.0.0.1
    Source Port: 1476

I used Process Monitor and Fiddler to investigate but to no avail.

Why would this work for 3rd party browsers but not with IE or System.Net.WebClient?

+1  A: 

Have you tried ...

new NetworkCredential( "peter", "password", "boxname" );

You might also try ...

var credCache = new CredentialCache();
credCache.Add( new Uri ("http://localhost/upload.aspx"),
                 "Negotiate",
                 new NetworkCredential("peter", "password", "boxname"));
wc.Credentials = credCache;

Also, according to this it may be that IIS is configured wrong. Try replacing "Negotiate" with "Basic" in the above and checking your IIS config for the website. There's also a bunch of possible causes here.

JP Alioto
Just tried it, same 401.2 response and 'Failure Audit'
Peter Hahndorf
Also tried the 'Negotiate' version, same result. What buffles me is that is also doesn't work in IE.
Peter Hahndorf
A: 

Without knowing your IIS deployment, and assuming that you have the correct authorization rules for upload set in IIS (e.g. the right allow* ACL's on the right dirs you are trying to upload content to, etc), first thing I would try is to set UseDefaultCredentials to true instead of explicitly set Credential. (Maybe you think you are accessing the server with the Credentials you are setting but that's not the case? That would be possible if this works.)

This is a very common scenario, so I would focus on IIS authorization rules for the directory in which you are trying to upload the file, the actual ACL's on that directory. For ex. is your site impersonating or not? if it is, then you have to have actual ACL's on that dir, otherwise whatever account app pool is running on.

Ariel
I don't think it is an ACL problem because it doesn't get that far, Process Monitor doesn't show any activity on the target directory.
Peter Hahndorf
Just tried it with UseDefaultCredentials, failed as well. I need to get it to work with non-Default credentials because Windows users are different on client and server machines in production.
Peter Hahndorf
+1  A: 

Try going into IE's options and explicitly add the site to the Intranet Zone. Then re-run the program. You should also not run the program from an administrator login. This may trigger the Enhanced Security Configuration for Internet Explorer.

It could explain why you can hit the site with Firefox and Opera, but not with IE or WebClient.

R Ubben
Good ideas, I tried both but it still doesn't work.
Peter Hahndorf
+1  A: 

I have seen a similar issue, where the Integrated / NTLM security will only work if you are accessing the host by machine name or localhost. In fact, it is a [poorly] document feature in Windows that is designed to protect against "reflection attacks".

Basically, you need to create a registry key on the machine that is trying to access the server, and whitelist the domain you are trying to hit. Each host name / FQDN needs to be on it's own line - there are no wildcards and the name must match exactly. From the KB Article:

  • Click Start, click Run, type regedit, and then click OK.
  • In Registry Editor, locate and then click the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
  • Right-click MSV1_0, point to New, and then click Multi-String Value.
  • Type BackConnectionHostNames, and then press ENTER.
  • Right-click BackConnectionHostNames, and then click Modify.
  • In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.
  • Exit Registry Editor, and then restart the computer.

http://support.microsoft.com/kb/956158/en-us

Goyuix
+10 If I could upvote this 10 times I would. Ended my 3 days of head scratching and Googling.
DancesWithBamboo