C#访问远程主机资源的方法
作者:网络转载 发布时间:[ 2015/5/12 11:54:16 ] 推荐标签:编程语言
四、角色模拟
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.IO;
namespace Test
{
public class Test
{
// logon types
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
// logon providers
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public 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)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
private WindowsImpersonationContext impersonationContext;
public bool impersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
// 这里使用LOGON32_LOGON_NEW_CREDENTIALS来访问远程资源。
// 如果要(通过模拟用户获得权限)实现服务器程序,访问本地授权数据库可
// 以用LOGON32_LOGON_INTERACTIVE
if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
System.AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
IPrincipal pr = System.Threading.Thread.CurrentPrincipal;
IIdentity id = pr.Identity;
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void undoImpersonation()
{
impersonationContext.Undo();
}
public void TestFunc()
{
bool isImpersonated = false;
try
{
if (impersonateValidUser("UserName", "Domain", "Password"))
{
isImpersonated = true;
//do what you want now, as the special user
// ...
File.Copy(@"\192.168.1.48generals ow.htm", "c:\now.htm", true);
}
}
finally
{
if (isImpersonated)
undoImpersonation();
}
}
}
}
五、比较
方法一通过调用Shell命令Net Use实现,有点笨拙。
方法二和方法一有些相似之处。映射远程资源,然后访问。
方法三由于会有超时异常出现,所以在网络速度快、传输小文件时是可以的。
方法四通过身份模拟实现远程资源访问。一些服务器进程是通过这种方式运行的。这种方法也是我的爱。
六、要注意的地方
关于这几种方法,google后都可以找到一些文章。但是等到自己实际测试时,有时会出现各种小错误,
这些错误基本来源于两方面:
1、函数的参数选择有问题,和自己的环境不相符。
比如
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
中的dwLogonType,要访问远程资源要用LOGON32_LOGON_NEW_CREDENTIALS,
要模拟本机用户要用LOGON32_LOGON_INTERACTIVE。
2、函数的参数格式有问题。
a、比如
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
中的lpszUserName、lpszDomain、lpszPassword要写清楚。
我在这遇到过问题,第一次测试时,远程服务器是一台独立的文件服务器,这是我的调用方式:
LogonUser("myname", "192.168.1.48", "password", LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
第二次测试时,远程服务器是域MyDomain中的一个成员服务器,提供文件服务。这时代码应该是:
LogonUser("myname", "MyDomain", "password", LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
注意,代码中是MyDomain而不是IP地址。
b、再如:
参考上面代码
string remote = @"\192.168.1.48generals";
string local = @"P:";
string username = @"DomainUserName";
string password = @"Password";
如果@"\192.168.1.48generals"变成@"\192.168.1.48generals”会出错;
如果是域中的用户,那么把@"DomainUserName"变成@"UserName"会出错。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南