How do you impersonate an Active Directory user in Powershell?

前端 未结 4 1080
执念已碎
执念已碎 2020-12-15 09:54

I\'m trying to run powershell commands through a web interface (ASP.NET/C#) in order to create mailboxes/etc on Exchange 2007. When I run the page using Visual Studio (Cassi

4条回答
  •  南笙
    南笙 (楼主)
    2020-12-15 10:40

    Here is a class that I use to impersonate a user.

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    
    namespace orr.Tools
    {
    
        #region Using directives.
        using System.Security.Principal;
        using System.Runtime.InteropServices;
        using System.ComponentModel;
        #endregion
    
        /// 
        /// Impersonation of a user. Allows to execute code under another
        /// user context.
        /// Please note that the account that instantiates the Impersonator class
        /// needs to have the 'Act as part of operating system' privilege set.
        /// 
        ///    
        /// This class is based on the information in the Microsoft knowledge base
        /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
        /// 
        /// Encapsulate an instance into a using-directive like e.g.:
        /// 
        ///     ...
        ///     using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
        ///     {
        ///         ...
        ///         [code that executes under the new context]
        ///         ...
        ///     }
        ///     ...
        /// 
        /// Please contact the author Uwe Keim (mailto:uwe.keim@zeta-software.de)
        /// for questions regarding this class.
        /// 
        public class Impersonator :
            IDisposable
        {
            #region Public methods.
            /// 
            /// Constructor. Starts the impersonation with the given credentials.
            /// Please note that the account that instantiates the Impersonator class
            /// needs to have the 'Act as part of operating system' privilege set.
            /// 
            /// The name of the user to act as.
            /// The domain name of the user to act as.
            /// The password of the user to act as.
            public Impersonator(
                string userName,
                string domainName,
                string password)
            {
                ImpersonateValidUser(userName, domainName, password);
            }
    
            // ------------------------------------------------------------------
            #endregion
    
            #region IDisposable member.
    
            public void Dispose()
            {
                UndoImpersonation();
            }
    
            // ------------------------------------------------------------------
            #endregion
    
            #region P/Invoke.
    
            [DllImport("advapi32.dll", SetLastError = true)]
            private static extern int LogonUser(
                string lpszUserName,
                string lpszDomain,
                string lpszPassword,
                int dwLogonType,
                int dwLogonProvider,
                ref IntPtr phToken);
    
            [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern int DuplicateToken(
                IntPtr hToken,
                int impersonationLevel,
                ref IntPtr hNewToken);
    
            [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern bool RevertToSelf();
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            private static extern bool CloseHandle(
                IntPtr handle);
    
            private const int LOGON32_LOGON_INTERACTIVE = 2;
            private const int LOGON32_PROVIDER_DEFAULT = 0;
    
            // ------------------------------------------------------------------
            #endregion
    
            #region Private member.
            // ------------------------------------------------------------------
    
            /// 
            /// Does the actual impersonation.
            /// 
            /// The name of the user to act as.
            /// The domain name of the user to act as.
            /// The password of the user to act as.
            private void ImpersonateValidUser(
                string userName,
                string domain,
                string password)
            {
                WindowsIdentity tempWindowsIdentity = null;
                IntPtr token = IntPtr.Zero;
                IntPtr tokenDuplicate = IntPtr.Zero;
    
                try
                {
                    if (RevertToSelf())
                    {
                        if (LogonUser(
                            userName,
                            domain,
                            password,
                            LOGON32_LOGON_INTERACTIVE,
                            LOGON32_PROVIDER_DEFAULT,
                            ref token) != 0)
                        {
                            if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                            {
                                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                                impersonationContext = tempWindowsIdentity.Impersonate();
                            }
                            else
                            {
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                            }
                        }
                        else
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                finally
                {
                    if (token != IntPtr.Zero)
                    {
                        CloseHandle(token);
                    }
                    if (tokenDuplicate != IntPtr.Zero)
                    {
                        CloseHandle(tokenDuplicate);
                    }
                }
            }
    
            /// 
            /// Reverts the impersonation.
            /// 
            private void UndoImpersonation()
            {
                if (impersonationContext != null)
                {
                    impersonationContext.Undo();
                }
            }
    
            private WindowsImpersonationContext impersonationContext = null;
    
            // ------------------------------------------------------------------
            #endregion
        }
    }
    

提交回复
热议问题