How do I handle WindowsImpersonationContext with HttpListener?

2

This may have been asked previously a slightly different way, but I have not yet satisfied myself completely.

With Visual Studio 2013, Windows 7, and a small C#/.NET 4.0 project, I am using an HttpListener to build a tiny web server in order to host some simple services and pages. Part of an upgrade to the existing project here was to start using integrated windows authentication.

One of the services this project offers is a way to connect to a SQL database - in order to run some canned updates. Using WindowsImpersonationContext and the correct HttpListener startup parameters, I was easily able to "impersonate" the authenticated user (via NTLM). Like so:

identity = (System.Security.Principal.WindowsIdentity)context.User.Identity;

using (System.Security.Principal.WindowsImpersonationContext wic = identity.Impersonate())
{
    doListenerCallback(context, lentry, true, identity);
}

The idea is that the credentials of the user accessing the web page is what's used to open the database connection. So this code is fine, and it gives me back an object, and all seems well.

Everything works correctly until I run this project (it is hosted inside a console app) using a regular user account (non-administrator). Impersonation still appears to happen, but my appdomain no longer allows assembly loading. I get stuff like this:

fact = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient");

Results in:

A first chance exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll

Additional information: Could not load file or assembly 'System.Data.OracleClient, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. Either a required impersonation level was not provided, or the provided impersonation level is invalid. (Exception from HRESULT: 0x80070542)

And I can't seem to do anything to get beyond this. I read elsewhere that it might be because a low priv account can't impersonate an admin account, at least without a UAC prompt.

If that is true, how does IIS manage to do this? Because I've done a lot of crazy ASP.Net stuff with impersonation, and never encountered this before.

We can certainly run this tool with an admin service account. But it just seems silly to do that - if impersonation exists, and it exists exactly for this kind of purpose, I'd like to know what I'm doing wrong and why it isn't working.

c#
visual-studio
httplistener
asked on Stack Overflow Jul 2, 2014 by John Doh • edited Jul 2, 2014 by Chris Barlow

1 Answer

3

I believe I have found the answer to this. Using antiduh's concept, I found this page:

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

Some Programs That Use Impersonation May Not Work Correctly After You Install Windows 2000 SP4

After you install Windows 2000 Service Pack 4 (SP4) on your computer, some programs that use impersonation may not work correctly.

This issue may occur in situations when the user account that is used to run the program does not have the "Impersonate a client after authentication" user right.

So that put me on that trail. That let me here http://blogs.technet.com/b/askds/archive/2008/11/25/fun-with-the-kerberos-delegation-web-site.aspx

Note This step is done to allow the IISKerbSvc (application pool identity) the ability to impersonate the user on the web server. If you look at the computer’s user right assignments you will see Impersonate a client after authentication and the IIS_WPG group is added there by default.

Oh, ok. So I dove down into my local security policy for my service user account, and this feature was not turned on for that account.

But once I added it... it worked! :)

Working Example

Notice my "wwtest" user account explicitly added here. Once I logged off/on, everything clicked into place.

So here is the answer. In order for impersonation to really work, you have to be a local administrator, or running as one of the built-in service accounts that already has that flag on, OR you have to go in here and turn this on

answered on Stack Overflow Jul 3, 2014 by John Doh

User contributions licensed under CC BY-SA 3.0