none
What am I doing wrong with Impersonation on HttpListener class? RRS feed

  • Question

  • Hello,

    I have a weird problem with the HttpListener class.  Please consider the following sample application:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (HttpListener h = new HttpListener())
                {
                    h.Prefixes.Add("http://+:8090/");
    
                    h.AuthenticationSchemes = AuthenticationSchemes.Ntlm;
    
                    h.Start();
    
                    Console.WriteLine("Running");
    
                    HttpListenerContext context = h.GetContext();
    
                    System.Security.Principal.WindowsIdentity identity = null;
                    identity = (System.Security.Principal.WindowsIdentity)context.User.Identity;
    
                    using (System.Security.Principal.WindowsImpersonationContext wic = identity.Impersonate())
                    {
                        System.Data.Common.DbProviderFactory fact = null;
                        fact = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient");
                    }
    
                    Console.ReadLine();
    
                    h.Stop();
                }
    
            }
        }
    }

    Our goal is to run this small console application as a light webserver.  It will run under a low-privilege service account.  Clients (Administrators, or people in certain security groups) will access a web page that it serves.  At that point, the program will impersonate them.  The impersonation will be used to enable an SSPI database connection to SQL Server.  Is this last part that doesn't work.

    If we run visual studio under Local Account "B", and debug run the program... if we then access the HttpListener with a different user account (i.e. my daily login) - and through Internet explorer - it appears that impersonation fails, or doesn't work totally, with this message:

    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)

    Example:

    http://i854.photobucket.com/albums/ab103/srVincentVega/error8_zpsilkay0bl.png

    See, it gets through the Impersonate() call no problem.  And I have verified that the CurrentIdentity does become the other user.  But then the library load failure has me stumped.  It's like it's impersonated the other account, but not actually done it.

    Even stranger is that the error references Oracle. But I am not referencing the Oracle provider at all in my code, so something really bad must be happening to freak it out like this.

    In this instance, both accounts are local admins.

    This has really been driving me nuts.  This is .net 4.5, Windows 8.1 64 bit.  Thank you


    Steve


    • Edited by Magnesium Thursday, February 19, 2015 2:48 AM more detail
    Thursday, February 19, 2015 2:45 AM

All replies

  • Some more info.  I went into my local Security Policy and turned these two features on for both of my test logins:

    Act as part of the operating system

    Impersonate a client after authentication

    Both of my test accounts are local admins, with the two SecPol features mentioned turned on. I logged out and back in just to make sure they took effect. Problem persists. If I run the console app normally, and do a run-as on internet explorer as the other user, it works. If I reverse this, and do run-as the console app , and run IE normally, then it fails. I logged out and back in as the other account and the same thing happens. It only occurs when the the console app is being "run as" that this happens


    Steve

    Thursday, February 19, 2015 2:50 PM
  • Even more info.  if I run the console app in the background as "User B" via a Windows Scheduled task, I don't have a problem.  It works.  So I'm thinking this is a red herring, and my problem was invoking the exe via "Run As Another user."  I thought this worked on Win7, but maybe I am wrong.  If anyone has any tech background on why it works as a scheduled background task but not when I do "run as," please let me know.  this is very frustrating

    Steve

    Thursday, February 19, 2015 3:41 PM
  • Hello Steve,

    From your description, it seems this could be a permission issue. Will your server host on the IIS, if so, you could follow this blog to add the added IIS_IUSRS group to the folder's NTFS permissions.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, February 20, 2015 8:30 AM
    Moderator
  • It is definitely a security/permissions issue.  Thanks for the link

    This is what I've determined: impersonation works if the executable is either running directly in that user's session (i.e. started with the mouse or keyboard), or if Windows launches it in the background via a scheduled task with stored credentials (i.e. start when machine boots).  In those two cases, everything works fine.

    It fails when the executable is shift-right-clicked and started with "run as different user."  It starts up and runs fine, is able to access the HttpListener library, open connections, and do all the rest.  When it picks up an http request and invokes impersonation, the impersonated context is what's unable to load any .NET libraries (Like the DbProviderFactory).   But all of this works fine when started as mentioned in the paragraph above.

    I am guessing this is something to do with behind-the-scenes restrictions with a "run as different user" process invocation.  I am almost certain I developed this application on Windows 7 using run as different user, and didn't have this issue.  Perhaps I don't remember correctly.  Or 8/8.1 has a new restriction

    The only reason I like run-as-different-user is because of the enormous convenience.  I can't think of any other way to debug impersonation that doesn't involve starting something in the background, where I'm then unable to do any kind of breakpointing or observation.


    Steve


    • Edited by Magnesium Friday, February 20, 2015 2:40 PM
    Friday, February 20, 2015 2:39 PM
  • Hello,

    As far as i know, windows 8/8.1 contains a more restrictive permissions management mechanism, for details, you could confirm it on the windws 8/8.1 forum:

    https://social.technet.microsoft.com/Forums/windows/en-US/home?category=w8itpro

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Tuesday, March 3, 2015 11:04 AM
    Moderator