windowsimpersonationcontext simple net logonuser impersonator impersonate impersonalizacion example c# impersonation

c# - simple - Iniciar un proceso.Net como un usuario diferente



simple impersonation c# example (2)

¿Puedes intentar algo como esto: iniciar un nuevo proceso como otro usuario?

Ejemplo de código:

System.Diagnostics.Process proc = new System.Diagnostics.Process(); System.Security.SecureString ssPwd = new System.Security.SecureString(); proc.StartInfo.UseShellExecute = false; proc.StartInfo.FileName = "filename"; proc.StartInfo.Arguments = "args..."; proc.StartInfo.Domain = "domainname"; proc.StartInfo.UserName = "username"; string password = "user entered password"; for (int x = 0; x < password.Length; x++) { ssPwd.AppendChar(password[x]); } password = ""; proc.StartInfo.Password = ssPwd; proc.Start();

Quiero iniciar un proceso con derechos de administrador. Cuando ejecuto el siguiente código, el proceso se queja de que necesita derechos de administrador:

public class ImpersonationHelper : IDisposable { IntPtr m_tokenHandle = new IntPtr(0); WindowsImpersonationContext m_impersonatedUser; #region Win32 API Declarations const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_LOGON_INTERACTIVE = 2; //This parameter causes LogonUser to create a primary token. [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); #endregion /// <summary> /// Constructor. Impersonates the requested user. Impersonation lasts until /// the instance is disposed. /// </summary> public ImpersonationHelper(string domain, string user, string password) { // Call LogonUser to obtain a handle to an access token. bool returnValue = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref m_tokenHandle); if (false == returnValue) { int ret = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(ret); } // Impersonate m_impersonatedUser = new WindowsIdentity(m_tokenHandle).Impersonate(); } #region IDisposable Pattern /// <summary> /// Revert to original user and cleanup. /// </summary> protected virtual void Dispose(bool disposing) { if (disposing) { // Revert to original user identity if (m_impersonatedUser != null) m_impersonatedUser.Undo(); } // Free the tokens. if (m_tokenHandle != IntPtr.Zero) CloseHandle(m_tokenHandle); } /// <summary> /// Explicit dispose. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Destructor /// </summary> ~ImpersonationHelper() { Dispose(false); } #endregion } using (new ImpersonationHelper("xxx.blabla.com", "xxxx", "xxxx")) { if (!string.IsNullOrEmpty(txtFilename.Text)) Process.Start(txtFilename.Text); }


Uso correcto de SecureString y algunos extras:

//You should use SecureString like the following SecureString password = new SecureString(); password.AppendChar(''p''); password.AppendChar(''a''); password.AppendChar(''s''); password.AppendChar(''s''); Process process = new Process(); process.StartInfo.UseShellExecute = false; //Set the working directory if you don''t execute something like calc or iisreset but your own exe in which you want to access some files etc.. process.StartInfo.WorkingDirectory = "workingDirectory"; //Full path (e.g. it can be @"C:/Windows/System32/iisreset.exe" OR you can use only file name if the path is included in Environment Variables..) process.StartInfo.FileName = @"fileName"; process.StartInfo.Domain = "domain"; process.StartInfo.UserName = "userName"; process.StartInfo.Password = password; process.Start();

EDIT: No sé por qué esta respuesta se vota por debajo de 0, tal vez se necesite un poco más de explicación. Si utilizará esto en un entorno no interactivo (como una aplicación web) y desea ejecutar un proceso con un usuario, tiene algunas opciones para usar la contraseña del usuario. Puede leer la contraseña desde un almacenamiento o desde un código. Una mejor manera; Puedes almacenarlo encriptado. Sin embargo, si planea usarlo en forma simple (tal vez temporalmente o solo para probar algo, etc.), puede usar SecureString de la manera que describí. La respuesta aceptada no utiliza SecureString de forma correcta. Leer la contraseña en una cadena desde la consola y luego colocarla en una SecureString es simplemente INCORRECTO. La respuesta aceptada NO asegura esa cadena o algo, sino que solo la engaña. Esa fue la motivación principal para que yo agregue esta respuesta. Compruebe el link .