浅谈在AD中的身份模拟

     如果在AD中要修改一个域用户的密码,而当前的操作用户并不具有域管理员的身份,将不会成功。所以说,要完成这个功能,必须能模拟域管理员的身份。下面提供了一个身份模拟类,代码如下:

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;

 

namespace SystemUser
{
    public class IdentityImpersonation
    {
        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
         int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
         int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);

        // 要模拟的用户的用户名、密码、域(机器名)
        private String _sImperUsername;
        private String _sImperPassword;
        private String _sImperDomain;
        // 记录模拟上下文
        private WindowsImpersonationContext _imperContext;
        private IntPtr _adminToken;
        private IntPtr _dupeToken;
        // 是否已停止模拟
        private Boolean _bClosed;
        public IdentityImpersonation(String impersonationUsername, String impersonationPassword, String impersonationDomain)
        {
            _sImperUsername = impersonationUsername;
            _sImperPassword = impersonationPassword;
            _sImperDomain = impersonationDomain;
            _adminToken = IntPtr.Zero;
            _dupeToken = IntPtr.Zero;
            _bClosed = true;
        }
        ~IdentityImpersonation()
        {
            if (!_bClosed)
            {
                StopImpersonate();
            }
        }
        public Boolean BeginImpersonate()
        {

            Boolean bLogined = LogonUser(_sImperUsername, _sImperDomain, _sImperPassword, 2, 0, ref _adminToken);

            if (!bLogined)
            {
                return false;
            }
            Boolean bDuped = DuplicateToken(_adminToken, 2, ref _dupeToken);
            if (!bDuped)
            {
                return false;
            }
            WindowsIdentity fakeId = new WindowsIdentity(_dupeToken);
            _imperContext = fakeId.Impersonate();
            _bClosed = false;
            return true;
        }
        public void StopImpersonate()
        {
            _imperContext.Undo();
            CloseHandle(_dupeToken);
            CloseHandle(_adminToken);
            _bClosed = true;
        }
    }
}

 

下面是IdentityImpersonation类使用的一个小例子:

 

        public void setPassWord(string guid, string password)
        {
            try
            {
                string imperPass = ConfigurationManager.AppSettings["ADPassword"];
                string imperDomain = getDomainName();

                IdentityImpersonation imper = new IdentityImpersonation("Administrator", imperPass, imperDomain);
               
                //开始模拟
                imper.BeginImpersonate();

                DirectoryEntry myDE = new DirectoryEntry(_getLDAPpathbyGUID(guid));
                ActiveDs.IADsUser user = (IADsUser)myDE.NativeObject;

                user.SetPassword(password);

                //停止模拟
                imper.StopImpersonate();

            }
            catch(Exception ex)
            {
                throw new Exception("设置密码失败!", ex);
            }

        }

 

 

你可能感兴趣的:(模拟)