views:

450

answers:

2

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

A: 

This may be the dumb obvious answer, but you could add your VMWare machine to the domain.

Martin Brown
Not if you don't have domain administration rights you cant.
sascha
I don't have domain admin rights, but my boss does. All I do is point out to him that I can't do any more work until the problem is resolved. As a result, my virtual machines get added fairly quickly.
Martin Brown
+1  A: 

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!

Ricardo Villamil