Search code examples
asp.netwindowsdnsvmwareimpersonation

ASP.NET: Impersonate against a domain on VMWare


I need to impersonate myself as a domain user in a ASP.NET application running on VMWare machine. Since the VMWare machine is not itself in the domain, ASP.NET is unable to resolve the user token (specified in web.config). Is there a way to do that?

Thanks in advance, Petr


Solution

  • I use this class I wrote all the time and it works like a charm!

    using System;
    using System.Security.Principal;
    
    /// <summary>
    /// Changes the security context the application runs under.
    /// </summary>
    public class ImpersonateHelper : IDisposable
    {
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);
    
        private IntPtr _token = IntPtr.Zero;
        private WindowsImpersonationContext _impersonatedUser = null;
    
        public IntPtr Token
        {
            get { return _token; }
            set { _token = value; }
        }
    
        public ImpersonateHelper(IntPtr token)
        {
            _token = token;
        }
    
        /// <summary>
        /// Switch the user to that set by the Token property
        /// </summary>
        public void Impersonate()
        {
            if (_token == IntPtr.Zero)
                _token = WindowsIdentity.GetCurrent().Token;
    
            _impersonatedUser = WindowsIdentity.Impersonate(_token);
        }
    
        /// <summary>
        /// Revert to the identity (user) before Impersonate() was called
        /// </summary>
        public void Undo()
        {
            if (_impersonatedUser != null)
                _impersonatedUser.Undo();
        }
    
        #region IDisposable Members
        private bool _isDisposed;
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed)
            {
                if (disposing)
                {
                    if (_impersonatedUser != null)
                        _impersonatedUser.Dispose();
    
                }
                CloseHandle(_token);
                _token = IntPtr.Zero;
            }
            _isDisposed = true;
        }
    
        ~ImpersonateHelper()
        {
            Dispose(false);
        }
        #endregion
    }
    

    Then you call it from the client class as:

    //Run task as the impersonated user and not as NETWORKSERVICE or ASPNET (in IIS5)
    try{
       impersonate.Impersonate();
       //Do work that needs to run as domain user here...
    }
    finally
    {
                //Revert impersonation to NETWORKSERVICE or ASPNET
                if (impersonate != null)
                {
                    impersonate.Undo();
                    impersonate.Dispose();
                }
    }
    

    Good Luck!