摘要:[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