[ASP.NET] 模擬特定Windows登入帳號

  • 1489
  • 0

摘要:[ASP.NET] 模擬特定Windows登入帳號

在工作上需要以特定的windows登入帳號,去存取某網路磁碟

因為該網路磁碟 只有特定的登入帳號才有權限

Code:

 
using System.Security.Principal;
using System.Runtime.InteropServices;
 
 
    public class LogonTest
    {
        private const int LOGON_TYPE_DEFAULT = 9;
        private const int PROVIDER_DEFAULT = 0;
 
        WindowsImpersonationContext impersonationContext;
 
        [DllImport("advapi32.dll")]
        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);
 
        /// <summary>
        ///  模擬登入 使用Default值: LOGON32_LOGON_TYPE = 9 ,  LOGON32_PROVIDER=0
        /// </summary>
        /// <param name="userName">登入帳號</param>
        /// <param name="domain">帳號之Domain</param>
        /// <param name="password">登入密碼</param>
        /// <returns></returns>
        public bool impersonateValidUser(String userName, String domain, String password)
        {
            return impersonateValidUser(userName, domain, password, LOGON32_LOGON_TYPE_DEFAULT, LOGON32_PROVIDER_DEFAULT);
        }
 
        public bool impersonateValidUser(String userName, String domain, String password, int logon32_logon, int logon32_provider)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;
            bool l_rtn = false;
            try
            {
                if (RevertToSelf())
                {
                    if (LogonUser(userName, domain, password, logon32_logon,
                        logon32_provider, ref token) != 0)
                    {
                        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                        {
                            tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                            impersonationContext = tempWindowsIdentity.Impersonate();
                            if (impersonationContext != null)
                            {
                                CloseHandle(token);
                                CloseHandle(tokenDuplicate);
                                l_rtn = true;
                            }
                        }
                    }
                    else
                    {
                        if (token != IntPtr.Zero)
                            CloseHandle(token);
                        if (tokenDuplicate != IntPtr.Zero)
                            CloseHandle(tokenDuplicate);
                    }
                }
 
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return l_rtn;
        }
       
        public void undoImpersonation()
        {
            impersonationContext.Undo();
        }
        #endregion
    }
 
    public enum LogonType
    {
        /// <summary>
        /// value 2: This logon type is intended for users who will be interactively using the computer, such as a user being logged on  
        /// by a terminal server, remote shell, or similar process.
        /// This logon type has the additional expense of caching logon information for disconnected operations; 
        /// therefore, it is inappropriate for some client/server applications,
        /// such as a mail server.
        /// </summary>
        LOGON32_LOGON_INTERACTIVE = 2,
 
        /// <summary>
        /// value 3:This logon type is intended for high performance servers to authenticate plaintext passwords.
        /// The LogonUser function does not cache credentials for this logon type.
        /// </summary>
        LOGON32_LOGON_NETWORK = 3,
 
        /// <summary>
        /// value 4:This logon type is intended for batch servers, where processes may be executing on behalf of a user without 
        /// their direct intervention. This type is also for higher performance servers that process many plaintext
        /// authentication attempts at a time, such as mail or Web servers. 
        /// The LogonUser function does not cache credentials for this logon type.
        /// </summary>
        LOGON32_LOGON_BATCH = 4,
 
        /// <summary>
        /// value 5:Indicates a service-type logon. The account provided must have the service privilege enabled. 
        /// </summary>
        LOGON32_LOGON_SERVICE = 5,
 
        /// <summary>
        /// value 7:This logon type is for GINA DLLs that log on users who will be interactively using the computer. 
        /// This logon type can generate a unique audit record that shows when the workstation was unlocked. 
        /// </summary>
        LOGON32_LOGON_UNLOCK = 7,
 
        /// <summary>
        /// value 8:This logon type preserves the name and password in the authentication package, which allows the server to make 
        /// connections to other network servers while impersonating the client. A server can accept plaintext credentials 
        /// from a client, call LogonUser, verify that the user can access the system across the network, and still 
        /// communicate with other servers.
        /// NOTE: Windows NT:  This value is not supported. 
        /// </summary>
        LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
 
        /// <summary>
        /// value 9:This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
        /// The new logon session has the same local identifier but uses different credentials for other network connections. 
        /// NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
        /// NOTE: Windows NT:  This value is not supported. 
        /// </summary>
        LOGON32_LOGON_NEW_CREDENTIALS = 9,
    }
 
    public enum LogonProvider
    {
        /// <summary>
        /// Use the standard logon provider for the system. 
        /// The default security provider is negotiate, unless you pass NULL for the domain name and the user name 
        /// is not in UPN format. In this case, the default provider is NTLM. 
        /// NOTE: Windows 2000/NT:   The default security provider is NTLM.
        /// </summary>
        LOGON32_PROVIDER_DEFAULT = 0,
        LOGON32_PROVIDER_WINNT35 = 1,
        LOGON32_PROVIDER_WINNT40 = 2,
        LOGON32_PROVIDER_WINNT50 = 3
    }
 
client use:
 
LogonTest l_test = new LogonTest();
l_test .impersonateValidUser("username","domainname","password");
 
 

 

 

 

 Refence:
http://support.microsoft.com/kb/306158/en-us
        // http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx