5

I am working on ASP.NET 4.0 MVC3 web application that works in intranet environment. The application makes use of Windows authentication. Its application pool is run by domain user that has spn set on a domain controller. Authentication works using Kerberos (on IE and Firefox after some additional configuration).

Now I want to upload files to sharepoint, but it's important for me to upload the file as the user currently logged in into the application (so the file is created on Sharepoint with his/her credentials).

I have the following code in ResourceExists(Uri uri) function:

'...
    Dim identity As System.Security.Principal.WindowsIdentity = HttpContext.User.Identity
    Dim impersonationContext = identity.Impersonate()
    response = request.GetResponse()
    impersonationContext.Undo()
'...

This works when running locally, but when I deploy to the server I get the exception:

System.Net.WebException: The remote server returned an error: (401) Unauthorized.\r\n   at WebDav.WebDavClient.ResourceExists(Uri uri)\r\n   at Website.Website.WebdavController.Upload(HttpPostedFileBase file, UploadViewModel vm)

I read something about passing on the credentials, that is not possible with NTLM, but I am sure I am using Kerberos (I checked the headers with wireshark and fiddler) and I see the following:

Authorization: Negotiate YIIFpQYGKwYBBQUCoIIFmTCCBZWgJDAiBgkqhkiC9x...

Any ideas why the impersonation does not work when running on the IIS server?

Michal B.
  • 5,676
  • 6
  • 42
  • 70

3 Answers3

4

I found the answer here:

http://support.microsoft.com/kb/810572

"Kerberos does not work in a load-balanced architecture and IIS drops back to NTLM authentication. Because you cannot use NTLM for delegation, any applications or services that require delegation do not work. For more information, click the following article number to view the article in the Microsoft"

And that was exactly the case. I tried now with another machine that is not load-balanced and it works.

The only thing that still surprises me is that ImpersonationLevel of the identity is still Impersonate not Delegate...

Michal B.
  • 5,676
  • 6
  • 42
  • 70
2

After setting <identity impersonate="true"/> in your web.config try the following:

using (((WindowsIdentity)User.Identity).Impersonate())
using (var client = new WebClient { Credentials = CredentialCache.DefaultNetworkCredentials })
{
    string result = client.DownloadString("http://sharepoint");
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • With `` my application runs as this user all the time. I cannot allow that. The web application needs to run as a custom domain account and is already configured for that. Only for this one line of code I need to access the network resource as the user currently logged in and not as the custom domain account that runs the app. Am I right here or am I missing something? I am currently looking at protocol transition (http://msdn.microsoft.com/en-us/library/ms998355.aspx) I think that applies in my case. Can you confirm? – Michal B. Jun 18 '12 at 09:51
  • I must use impersonate="true" otherwise I get ImpersonationLevel `Identify`. So I use it with username and password of the DOMAIN\USER that I want to run the app as. – Michal B. Jun 21 '12 at 08:19
1

you need to configure your site correctly in IIS for impersonation to work.

see Configure ASP.NET Impersonation Authentication (IIS 7)

marc.d
  • 3,804
  • 5
  • 31
  • 46
  • I have IIS6. But anyway, this only configures the web.config. I do not want that. My application needs to run as DOMAIN\USER and only some request within my app to external resources must be done as the user that is logged in. I get the WindowsIdentity and I call Impersonate(), but there are no credentials in CredentialCache (they are both empty...) – Michal B. Jun 19 '12 at 13:20
  • I upvoted both answers, because they include part of the configuration that needed to be done. In my case the problem was a load balancer... – Michal B. Jun 21 '12 at 08:20