为实现线程用户的切换,我们需要依靠 advapi32.dll 中的 LogonUser 方法。advapi32.dll 是非托管代码程序,我们怎么调用它哪?
使用非托管代码的前提是需要有 UnmanagedCode 权限,该权限是默认授予的。
然后确定要用哪个非托管的DLL,然后在托管代码中声明一个与非托管代码中方法相匹配的方法:
这样我们可以象使用托管代码一样使用它:
用户切换功能的代码如下:
部署时,非托管代码的DLL放在调用其功能的程序的同一目录下。
使用非托管代码的前提是需要有 UnmanagedCode 权限,该权限是默认授予的。
然后确定要用哪个非托管的DLL,然后在托管代码中声明一个与非托管代码中方法相匹配的方法:
[DllImport(
@"
advapi32.dll
"
)]
public static extern bool logonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
public static extern bool logonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
这样我们可以象使用托管代码一样使用它:
bool
loggedOn
=
LogonUser(
"
xin
"
,
"
mydomain
"
,
"
password
"
, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, phToken);
用户切换功能的代码如下:
//
declare for p/invoke
[DllImport( @" advapi32.dll " , SetLastError = true )]
public static extern bool logonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport( @" advapi32.dll " , CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
private WindowsImpersonationContent impersonationContext = null ;
public void Switch( string userName, string password, string domain)
{
IntPtr token = IntPtr.Zero;
WindowsImpersonationContext impersonationContext = null;
// log on as the give user account
bool loggedOn = LogonUser(userName, domain, password, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, out token);
if (loggedOn == false)
{
throw new System.SecurityException(userName + " logon failed");
}
IntPtr tokenDuplicate = IntPtr.Zero;
WindowsIdentity tempWindowsIdentity = null;
// duplicate the security token
if (DuplicateToken(token, SecurityImpersonation, ref tokenDuplicate) != false)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
// change the current thread's run-as to the new window identity.
impersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new System.Security.SecurityException("Logon use failed");
}
}
[DllImport( @" advapi32.dll " , SetLastError = true )]
public static extern bool logonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport( @" advapi32.dll " , CharSet = CharSet.Auto, SetLastError = true )]
public static extern bool DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
private WindowsImpersonationContent impersonationContext = null ;
public void Switch( string userName, string password, string domain)
{
IntPtr token = IntPtr.Zero;
WindowsImpersonationContext impersonationContext = null;
// log on as the give user account
bool loggedOn = LogonUser(userName, domain, password, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, out token);
if (loggedOn == false)
{
throw new System.SecurityException(userName + " logon failed");
}
IntPtr tokenDuplicate = IntPtr.Zero;
WindowsIdentity tempWindowsIdentity = null;
// duplicate the security token
if (DuplicateToken(token, SecurityImpersonation, ref tokenDuplicate) != false)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
// change the current thread's run-as to the new window identity.
impersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new System.Security.SecurityException("Logon use failed");
}
}
部署时,非托管代码的DLL放在调用其功能的程序的同一目录下。