■ 윈도우 서비스 내에서 사용자 계정 변경하기

------------------------------------------------------------------------------------------------------------------------


TestService.zip


ImpersonationHelper.cs

 

 

using System;

using System.Runtime.InteropServices;

using System.Security.Principal;

 

namespace TestService

{

    /// <summary>

    /// 가장 헬퍼

    /// </summary>

    public class ImpersonationHelper : IDisposable

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 사용자 로그온 하기 - LogonUser(userAccount, domain, password, logonType, logonProvider, tokenHandle)

 

        /// <summary>

        /// 사용자 로그온 하기

        /// </summary>

        /// <param name="userAccount">사용자 계정</param>

        /// <param name="domain">도메인</param>

        /// <param name="password">패스워드</param>

        /// <param name="logonType">로그온 타입</param>

        /// <param name="logonProvider">로그온 제공자</param>

        /// <param name="tokenHandle">토큰 핸들</param>

        /// <returns>처리 결과</returns>

        [DllImport("advapi32.dll", SetLastError = true)]

        private static extern bool LogonUser(string userAccount, string domain, string password, int logonType, int logonProvider,

            ref IntPtr tokenHandle);

 

        #endregion

        #region 핸들 닫기 - CloseHandle(tokenHandle)

 

        /// <summary>

        /// 핸들 닫기

        /// </summary>

        /// <param name="tokenHandle">토큰 핸들</param>

        /// <returns>처리 결과</returns>

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

        private extern static bool CloseHandle(IntPtr tokenHandle);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 토큰 핸들

        /// </summary>

        private IntPtr tokenHandle = IntPtr.Zero;

 

        /// <summary>

        /// 윈도우즈 식별자

        /// </summary>

        private WindowsIdentity windowsIdentity;

 

        /// <summary>

        /// 윈도우즈 가장 컨텍스트

        /// </summary>

        private WindowsImpersonationContext windowsImpersonationContext;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - ImpersonationHelper(domain, userAccount, password)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="domain">도메인</param>

        /// <param name="userAccount">사용자 계정</param>

        /// <param name="password">패스워드</param>

        public ImpersonationHelper(string domain, string userAccount, string password)

        {

            if(LogonUser(userAccount, domain, password, 3, 0, ref this.tokenHandle))

            {

                this.windowsIdentity = new WindowsIdentity(this.tokenHandle);

 

                this.windowsImpersonationContext = this.windowsIdentity.Impersonate();

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 리소스 해제하기 - Dispose()

 

        /// <summary>

        /// 리소스 해제하기

        /// </summary>

        public void Dispose()

        {

            this.windowsImpersonationContext.Undo();

 

            this.windowsImpersonationContext.Dispose();

 

            this.windowsIdentity.Dispose();

 

            if(this.tokenHandle != IntPtr.Zero)

            {

                CloseHandle(this.tokenHandle);

            }

 

            this.tokenHandle = IntPtr.Zero;

        }

 

        #endregion

    }

}

 

 

WindowService.cs

 

 

using System;

using System.Security.Principal;

using System.ServiceProcess;

 

namespace TestService

{

    /// <summary>

    /// 윈도우 서비스

    /// </summary>

    public partial class WindowService : ServiceBase

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - WindowService()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public WindowService()

        {

            AutoLog     = false;

            ServiceName = "ServiceName";

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 테스트 하기 - Test(argumentArray)

 

        /// <summary>

        /// 테스트 하기

        /// </summary>

        /// <param name="argumentArray">인자 배열</param>

        /// <remarks>디버그 모드시 실행된다.</remarks>

        public void Test(string[] argumentArray)

        {

            OnStart(argumentArray);

 

            Console.ReadLine();

 

            OnStop();

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 시작시 처리하기 - OnStart(argumentArray)

 

        /// <summary>

        /// 시작시 처리하기

        /// </summary>

        /// <param name="argumentArray">인자 배열</param>

        protected override void OnStart(string[] argumentArray)

        {

            FileLogHelper logHelper = new FileLogHelper("d:\\", "service.log");

 

            WindowsIdentity windowsIdentity;

 

            windowsIdentity = WindowsIdentity.GetCurrent();

 

            logHelper.WriteLog("현재 윈도우즈 신원");

            logHelper.WriteLog("----------------------------------------"     );

            logHelper.WriteLog("사용자 계정 : {0}", windowsIdentity.Name      );

            logHelper.WriteLog("사용자 SDDL : {0}", windowsIdentity.User.Value);

 

            using(ImpersonationHelper helper = new ImpersonationHelper("kingdom", "test", "1234"))

            {

                windowsIdentity = WindowsIdentity.GetCurrent();

 

                logHelper.WriteLog("현재 윈도우즈 신원");

                logHelper.WriteLog("----------------------------------------"     );

                logHelper.WriteLog("사용자 계정 : {0}", windowsIdentity.Name      );

                logHelper.WriteLog("사용자 SDDL : {0}", windowsIdentity.User.Value);

            }

 

            windowsIdentity = WindowsIdentity.GetCurrent();

 

            logHelper.WriteLog("현재 윈도우즈 신원");

            logHelper.WriteLog("----------------------------------------"     );

            logHelper.WriteLog("사용자 계정 : {0}", windowsIdentity.Name      );

            logHelper.WriteLog("사용자 SDDL : {0}", windowsIdentity.User.Value);

        }

 

        #endregion

        #region 중단시 처리하기 - OnStop()

 

        /// <summary>

        /// 중단시 처리하기

        /// </summary>

        protected override void OnStop()

        {

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요