通过身份模拟实现远程资源访问
以下内容来源:http://www.cnblogs.com/h2appy/articles/1204277.html
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.InteropServices; 6 7 namespace WebApplication1 8 { 9 public class WNetHelper 10 { 11 12 #region 通过身份模拟实现远程资源访问 13 14 // logon types 15 const int LOGON32_LOGON_INTERACTIVE = 2; 16 const int LOGON32_LOGON_NETWORK = 3; 17 const int LOGON32_LOGON_NEW_CREDENTIALS = 9; 18 // logon providers 19 const int LOGON32_PROVIDER_DEFAULT = 0; 20 const int LOGON32_PROVIDER_WINNT50 = 3; 21 const int LOGON32_PROVIDER_WINNT40 = 2; 22 const int LOGON32_PROVIDER_WINNT35 = 1; 23 24 [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 25 public static extern int LogonUser(String lpszUserName, 26 String lpszDomain, 27 String lpszPassword, 28 int dwLogonType, 29 int dwLogonProvider, 30 ref IntPtr phToken); 31 32 [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 33 public static extern int DuplicateToken(IntPtr hToken, 34 int impersonationLevel, 35 ref IntPtr hNewToken); 36 37 [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 38 public static extern bool RevertToSelf(); 39 40 [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 41 public static extern bool CloseHandle(IntPtr handle); 42 43 private static System.Security.Principal.WindowsImpersonationContext impersonationContext; 44 /// <summary> 45 /// 连接网络资源 46 /// </summary> 47 /// <param name="domain">IP/计算机名</param> 48 /// <param name="userName">用户名</param> 49 /// <param name="password">密码</param> 50 /// <returns></returns> 51 public static bool impersonateValidUser(String domain, String userName, String password) 52 { 53 System.Security.Principal.WindowsIdentity tempWindowsIdentity; 54 IntPtr token = IntPtr.Zero; 55 IntPtr tokenDuplicate = IntPtr.Zero; 56 57 if (RevertToSelf()) 58 { 59 // 这里使用LOGON32_LOGON_NEW_CREDENTIALS来访问远程资源。 60 // 如果要(通过模拟用户获得权限)实现服务器程序,访问本地授权数据库可 61 // 以用LOGON32_LOGON_INTERACTIVE 62 if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, 63 LOGON32_PROVIDER_DEFAULT, ref token) != 0) 64 { 65 if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 66 { 67 tempWindowsIdentity = new System.Security.Principal.WindowsIdentity(tokenDuplicate); 68 impersonationContext = tempWindowsIdentity.Impersonate(); 69 if (impersonationContext != null) 70 { 71 System.AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal); 72 System.Security.Principal.IPrincipal pr = System.Threading.Thread.CurrentPrincipal; 73 System.Security.Principal.IIdentity id = pr.Identity; 74 CloseHandle(token); 75 CloseHandle(tokenDuplicate); 76 return true; 77 } 78 } 79 } 80 } 81 if (token != IntPtr.Zero) 82 CloseHandle(token); 83 if (tokenDuplicate != IntPtr.Zero) 84 CloseHandle(tokenDuplicate); 85 return false; 86 } 87 88 public static void undoImpersonation() 89 { 90 impersonationContext.Undo(); 91 } 92 93 #endregion 94 } 95 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.IO; 8 9 namespace WebApplication1 10 { 11 public partial class WebForm1 : System.Web.UI.Page 12 { 13 protected void Page_Load(object sender, EventArgs e) 14 { 15 TestFunc(); 16 17 } 18 19 public void TestFunc() 20 { 21 bool isImpersonated = false; 22 try 23 { 24 if (WNetHelper.impersonateValidUser("Netnetnet-pc", "admin2", "123")) 25 { 26 isImpersonated = true; 27 System.IO.File.Copy(@"\\Netnetnet-pc\站点发布\a.txt", "d:\\a1.txt", true); 28 } 29 } 30 finally 31 { 32 if (isImpersonated) 33 WNetHelper.undoImpersonation(); 34 } 35 } 36 } 37 }