.net下模拟不同身份登陆以获取不同权限
  1 .net下模拟不同身份登陆以获取不同权限
.net下模拟不同身份登陆以获取不同权限  
2 
 
3 作者:佚名 时间:2004-04-16 09:14 出处:互连网 责编:chinaitpower
作者:佚名 时间:2004-04-16 09:14 出处:互连网 责编:chinaitpower  
4 
 
5 摘要:.net下模拟不同身份登陆以获取不同权限
              摘要:.net下模拟不同身份登陆以获取不同权限 
6 
 
7 
 
8 不管是asp.net、web service还是window service,程序运行的时候只有本地计算机的部分权限,有时候需要更大的权限,比如读写某台服务器或域中的一台计算机上的文件等,这就需要更大的权限,比如域帐户权限。
不管是asp.net、web service还是window service,程序运行的时候只有本地计算机的部分权限,有时候需要更大的权限,比如读写某台服务器或域中的一台计算机上的文件等,这就需要更大的权限,比如域帐户权限。 
9
10 通过获取不同身份的WindowsImpersonationContext对象,可以模拟不同用户登陆,请看我生成的NetworkSecurity类的
通过获取不同身份的WindowsImpersonationContext对象,可以模拟不同用户登陆,请看我生成的NetworkSecurity类的 
11 public static WindowsImpersonationContext ImpersonateUser(string strDomain,
public static WindowsImpersonationContext ImpersonateUser(string strDomain, 
12 string strLogin,
string strLogin, 
13
14 string strPwd,
string strPwd, 
15
16 LogonType logonType,
LogonType logonType, 
17
18 LogonProvider logonProvider);
LogonProvider logonProvider); 
19
20 附NetworkSecurity.cs源代码如下:
附NetworkSecurity.cs源代码如下: 
21
22 /*
/* 
23 * Author : TongWei
* Author : TongWei 
24 * Date : 2005-1-25
* Date : 2005-1-25 
25 * Rights : China Netwave Inc.@2005
* Rights : China Netwave Inc.@2005 
26 */
*/ 
27
28 using System;
using System; 
29 using System.Runtime.InteropServices;
using System.Runtime.InteropServices; 
30 using System.Security.Principal;
using System.Security.Principal; 
31 using System.Security.Permissions;
using System.Security.Permissions; 
32
33 namespace CNW.OMP.Common.Utility
namespace CNW.OMP.Common.Utility 
34 {
{ 
35 public enum LogonType : int
public enum LogonType : int 
36 {
{ 
37 /// <summary>
/// <summary> 
38 /// This logon type is intended for users who will be interactively using the computer, such as a user
/// This logon type is intended for users who will be interactively using the computer, such as a user 
39 /// being logged on by a terminal server, remote shell, or similar process. This logon type has the
/// being logged on by a terminal server, remote shell, or similar process. This logon type has the 
40 /// additional expense of caching logon information for disconnected operation, and is therefore
/// additional expense of caching logon information for disconnected operation, and is therefore 
41 /// inappropriate for some client/server applications, such as a mail server.
/// inappropriate for some client/server applications, such as a mail server. 
42 /// </summary>
/// </summary> 
43 LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_INTERACTIVE = 2, 
44
45 /// <summary>
/// <summary> 
46 /// This logon type is intended for high performance servers to authenticate clear text passwords.
/// This logon type is intended for high performance servers to authenticate clear text passwords. 
47 /// The LogonUser function does not cache credentials for this logon type.
/// The LogonUser function does not cache credentials for this logon type. 
48 /// </summary>
/// </summary> 
49 LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_NETWORK = 3, 
50
51 /// <summary>
/// <summary> 
52 /// This logon type is intended for batch servers, where processes may be executing on behalf of a user
/// This logon type is intended for batch servers, where processes may be executing on behalf of a user 
53 /// without their direct intervention; or for higher performance servers that process many clear-text
/// without their direct intervention; or for higher performance servers that process many clear-text 
54 /// authentication attempts at a time, such as mail or web servers. The LogonUser function does not cache
/// authentication attempts at a time, such as mail or web servers. The LogonUser function does not cache 
55 /// credentials for this logon type.
/// credentials for this logon type. 
56 /// </summary>
/// </summary> 
57 LOGON32_LOGON_BATCH = 4,
LOGON32_LOGON_BATCH = 4, 
58
59 /// <summary>
/// <summary> 
60 /// Indicates a service-type logon. The account provided must have the service privilege enabled.
/// Indicates a service-type logon. The account provided must have the service privilege enabled. 
61 /// </summary>
/// </summary> 
62 LOGON32_LOGON_SERVICE = 5,
LOGON32_LOGON_SERVICE = 5, 
63
64 /// <summary>
/// <summary> 
65 /// This logon type is intended for GINA DLLs logging on users who will be interactively using the computer.
/// This logon type is intended for GINA DLLs logging on users who will be interactively using the computer. 
66 /// This logon type allows a unique audit record to be generated that shows when the workstation was unlocked.
/// This logon type allows a unique audit record to be generated that shows when the workstation was unlocked. 
67 /// </summary>
/// </summary> 
68 LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_UNLOCK = 7, 
69
70 /// <summary>
/// <summary> 
71 /// Windows XP/2000: This logon type preserves the name and password in the authentication packages,
/// Windows XP/2000: This logon type preserves the name and password in the authentication packages, 
72 /// allowing the server to make connections to other network servers while impersonating the client.
/// allowing the server to make connections to other network servers while impersonating the client. 
73 /// This allows a server to accept clear text credentials from a client, call LogonUser, verify that
/// This allows a server to accept clear text credentials from a client, call LogonUser, verify that 
74 /// the user can access the system across the network, and still communicate with other servers.
/// the user can access the system across the network, and still communicate with other servers. 
75 /// </summary>
/// </summary> 
76 LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
LOGON32_LOGON_NETWORK_CLEARTEXT = 8, 
77
78 /// <summary>
/// <summary> 
79 /// Windows XP/2000: This logon type allows the caller to clone its current token and specify new credentials
/// Windows XP/2000: This logon type allows the caller to clone its current token and specify new credentials 
80 /// for outbound connections. The new logon session has the same local identity, but uses different credentials
/// for outbound connections. The new logon session has the same local identity, but uses different credentials 
81 /// for other network connections.
/// for other network connections. 
82 /// This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
/// This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider. 
83 /// </summary>
/// </summary> 
84 LOGON32_LOGON_NEW_CREDENTIALS = 9
LOGON32_LOGON_NEW_CREDENTIALS = 9 
85 };
}; 
86
87 public enum LogonProvider : int
public enum LogonProvider : int 
88 {
{ 
89 /// <summary>
/// <summary> 
90 /// Use the standard logon provider for the system. The default security provider is NTLM.
/// Use the standard logon provider for the system. The default security provider is NTLM. 
91 /// Windows XP: The default provider is negotiate, unless you pass NULL for the domain name and
/// Windows XP: The default provider is negotiate, unless you pass NULL for the domain name and 
92 /// the user name is not in UPN format. In this case the default provider is NTLM.
/// the user name is not in UPN format. In this case the default provider is NTLM. 
93 /// </summary>
/// </summary> 
94 LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_DEFAULT = 0, 
95
96 /// <summary>
/// <summary> 
97 /// Use the Windows NT 3.5 logon provider.
/// Use the Windows NT 3.5 logon provider. 
98 /// </summary>
/// </summary> 
99 LOGON32_PROVIDER_WINNT35 = 1,
LOGON32_PROVIDER_WINNT35 = 1, 
100
101 /// <summary>
/// <summary> 
102 /// Use the NTLM logon provider.
/// Use the NTLM logon provider. 
103 /// </summary>
/// </summary> 
104 LOGON32_PROVIDER_WINNT40 = 2,
LOGON32_PROVIDER_WINNT40 = 2, 
105
106 /// <summary>
/// <summary> 
107 /// Windows XP/2000: Use the negotiate logon provider.
/// Windows XP/2000: Use the negotiate logon provider. 
108 /// </summary>
/// </summary> 
109 LOGON32_PROVIDER_WINNT50 = 3
LOGON32_PROVIDER_WINNT50 = 3 
110 };
}; 
111
112 class SecuUtil32
class SecuUtil32 
113 {
{ 
114 [DllImport("advapi32.dll", SetLastError=true)]
[DllImport("advapi32.dll", SetLastError=true)] 
115 public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, 
116 int dwLogonType, int dwLogonProvider, ref IntPtr TokenHandle);
int dwLogonType, int dwLogonProvider, ref IntPtr TokenHandle); 
117
118 [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
[DllImport("kernel32.dll", CharSet=CharSet.Auto)] 
119 public extern static bool CloseHandle(IntPtr handle);
public extern static bool CloseHandle(IntPtr handle); 
120
121 [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
122 public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, 
123 int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); 
124 }
} 
125
126 public class NetworkSecurity
public class NetworkSecurity 
127 {
{ 
128 public NetworkSecurity()
public NetworkSecurity() 
129 {
{ 
130 //
// 
131 // TODO: Add constructor logic here
// TODO: Add constructor logic here 
132 //
// 
133 }
} 
134
135 /// <summary>
/// <summary> 
136 /// The ImpersonateUser function attempts to log a user on to the local computer.
/// The ImpersonateUser function attempts to log a user on to the local computer. 
137 /// The local computer is the computer from which ImpersonateUser was called.
/// The local computer is the computer from which ImpersonateUser was called. 
138 /// You cannot use ImpersonateUser to log on to a remote computer.
/// You cannot use ImpersonateUser to log on to a remote computer. 
139 /// You specify the user with a user name and domain, and authenticate the user with a clear-text password.
/// You specify the user with a user name and domain, and authenticate the user with a clear-text password. 
140 /// If the function succeeds, you receive a handle to a token that represents the logged-on user.
/// If the function succeeds, you receive a handle to a token that represents the logged-on user. 
141 /// You can then use this token handle to impersonate the specified user, or in most cases,
/// You can then use this token handle to impersonate the specified user, or in most cases, 
142 /// to create a process running in the context of the specified user.
/// to create a process running in the context of the specified user. 
143 /// </summary>
/// </summary> 
144 /// <param name="strDomain">
/// <param name="strDomain"> 
145 /// specifies the name of the domain or server whose account database contains the strLogin account.
/// specifies the name of the domain or server whose account database contains the strLogin account. 
146 /// </param>
/// </param> 
147 /// <param name="strLogin">specifies the name of the user.</param>
/// <param name="strLogin">specifies the name of the user.</param> 
148 /// <param name="strPwd">specifies the clear-text password for the user account specified by strLogin.</param>
/// <param name="strPwd">specifies the clear-text password for the user account specified by strLogin.</param> 
149 /// <param name="logonType">Specifies the type of logon operation to perform.</param>
/// <param name="logonType">Specifies the type of logon operation to perform.</param> 
150 /// <param name="logonProvider">Specifies the logon provider.</param>
/// <param name="logonProvider">Specifies the logon provider.</param> 
151 /// <example>
/// <example> 
152 /// //Add System.Security.dll
/// //Add System.Security.dll 
153 /// //using System.Security.Principal;
/// //using System.Security.Principal; 
154 ///
/// 
155 /// string strDomain=ConfigurationSettings.AppSettings["mSALoginDomainName"];
/// string strDomain=ConfigurationSettings.AppSettings["mSALoginDomainName"]; 
156 /// string strUser=ConfigurationSettings.AppSettings["mSALoginDomainUser"];
/// string strUser=ConfigurationSettings.AppSettings["mSALoginDomainUser"]; 
157 /// string strPassword=ConfigurationSettings.AppSettings["mSALoginDomainPassword"];
/// string strPassword=ConfigurationSettings.AppSettings["mSALoginDomainPassword"]; 
158 ///
/// 
159 /// WindowsImpersonationContext impContext = null;
/// WindowsImpersonationContext impContext = null; 
160 /// try
/// try 
161 /// {
/// { 
162 /// impContext = NetworkSecurity.ImpersonateUser(strDomain,strUser,strPassword,
/// impContext = NetworkSecurity.ImpersonateUser(strDomain,strUser,strPassword, 
163 /// LogonType.LOGON32_LOGON_SERVICE,
/// LogonType.LOGON32_LOGON_SERVICE, 
164 /// LogonProvider.LOGON32_PROVIDER_DEFAULT);
/// LogonProvider.LOGON32_PROVIDER_DEFAULT); 
165 /// }
/// } 
166 /// catch
/// catch 
167 /// {
/// { 
168 ///
/// 
169 /// }
/// } 
170 ///
/// 
171 /// //work under this logined user
/// //work under this logined user 
172 ///
/// 
173 /// impContext.Undo();
/// impContext.Undo(); 
174 /// </example>
/// </example> 
175 /// <returns>
/// <returns> 
176 /// </returns>
/// </returns> 
177 public static WindowsImpersonationContext ImpersonateUser(string strDomain,
public static WindowsImpersonationContext ImpersonateUser(string strDomain, 
178 string strLogin,
string strLogin, 
179 string strPwd,
string strPwd, 
180 LogonType logonType,
LogonType logonType, 
181 LogonProvider logonProvider)
LogonProvider logonProvider) 
182 {
{ 
183 // Initialize tokens
// Initialize tokens 
184 IntPtr tokenHandle = new IntPtr(0);
IntPtr tokenHandle = new IntPtr(0); 
185 IntPtr dupeTokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0); 
186 tokenHandle = IntPtr.Zero;
tokenHandle = IntPtr.Zero; 
187 dupeTokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero; 
188
189 // If domain name was blank, assume local machine
// If domain name was blank, assume local machine 
190 if (strDomain == "")
if (strDomain == "") 
191 strDomain = System.Environment.MachineName;
strDomain = System.Environment.MachineName; 
192
193 try
try 
194 {
{ 
195 const int SecurityImpersonation = 2;
const int SecurityImpersonation = 2; 
196
197 // Call LogonUser to obtain a handle to an access token.
// Call LogonUser to obtain a handle to an access token. 
198 bool returnValue = SecuUtil32.LogonUser(
bool returnValue = SecuUtil32.LogonUser( 
199 strLogin,
strLogin, 
200 strDomain,
strDomain, 
201 strPwd,
strPwd, 
202 (int)logonType,
(int)logonType, 
203 (int)logonProvider,
(int)logonProvider, 
204 ref tokenHandle);
ref tokenHandle); 
205
206 // Did impersonation fail?
// Did impersonation fail? 
207 if (false == returnValue)
if (false == returnValue) 
208 {
{ 
209 int ret = Marshal.GetLastWin32Error();
int ret = Marshal.GetLastWin32Error(); 
210 // Throw the exception show the reason why LogonUser failed
// Throw the exception show the reason why LogonUser failed 
211 string strErr = String.Format("LogonUser failed with error code : {0}", ret);
string strErr = String.Format("LogonUser failed with error code : {0}", ret); 
212 throw new ApplicationException(strErr, null);
throw new ApplicationException(strErr, null); 
213 }
} 
214
215 // Get identity before impersonation
// Get identity before impersonation 
216 bool retVal = SecuUtil32.DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
bool retVal = SecuUtil32.DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle); 
217
218 // Did DuplicateToken fail?
// Did DuplicateToken fail? 
219 if (false == retVal)
if (false == retVal) 
220 {
{ 
221 // Close existing handle
// Close existing handle 
222 SecuUtil32.CloseHandle(tokenHandle);
SecuUtil32.CloseHandle(tokenHandle); 
223 // Throw the exception show the reason why DuplicateToken failed
// Throw the exception show the reason why DuplicateToken failed 
224 throw new ApplicationException("Failed to duplicate token", null);
throw new ApplicationException("Failed to duplicate token", null); 
225 }
} 
226
227 // Create new identity using new primary token
// Create new identity using new primary token 
228 // The token that is passed to the following constructor must
// The token that is passed to the following constructor must 
229 // be a primary token in order to use it for impersonation.
// be a primary token in order to use it for impersonation. 
230 WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle); 
231 WindowsImpersonationContext impersonatedUser = newId.Impersonate();
WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 
232
233 return impersonatedUser;
return impersonatedUser; 
234 }
} 
235 catch (Exception ex)
catch (Exception ex) 
236 {
{ 
237 throw new ApplicationException(ex.Message, ex);
throw new ApplicationException(ex.Message, ex); 
238 }
} 
239 finally
finally 
240 {
{ 
241 // Close handle
// Close handle 
242 if (tokenHandle != IntPtr.Zero)
if (tokenHandle != IntPtr.Zero) 
243 SecuUtil32.CloseHandle(tokenHandle);
SecuUtil32.CloseHandle(tokenHandle); 
244 if (dupeTokenHandle != IntPtr.Zero)
if (dupeTokenHandle != IntPtr.Zero) 
245 SecuUtil32.CloseHandle(dupeTokenHandle);
SecuUtil32.CloseHandle(dupeTokenHandle); 
246 }
} 
247 }
} 
248 }
} 
249 }
} 
250 
 
251 
 
252
 .net下模拟不同身份登陆以获取不同权限
.net下模拟不同身份登陆以获取不同权限  2
 
 3
 作者:佚名 时间:2004-04-16 09:14 出处:互连网 责编:chinaitpower
作者:佚名 时间:2004-04-16 09:14 出处:互连网 责编:chinaitpower  4
 
 5
 摘要:.net下模拟不同身份登陆以获取不同权限
              摘要:.net下模拟不同身份登陆以获取不同权限 6
 
 7
 
 8
 不管是asp.net、web service还是window service,程序运行的时候只有本地计算机的部分权限,有时候需要更大的权限,比如读写某台服务器或域中的一台计算机上的文件等,这就需要更大的权限,比如域帐户权限。
不管是asp.net、web service还是window service,程序运行的时候只有本地计算机的部分权限,有时候需要更大的权限,比如读写某台服务器或域中的一台计算机上的文件等,这就需要更大的权限,比如域帐户权限。 9

10
 通过获取不同身份的WindowsImpersonationContext对象,可以模拟不同用户登陆,请看我生成的NetworkSecurity类的
通过获取不同身份的WindowsImpersonationContext对象,可以模拟不同用户登陆,请看我生成的NetworkSecurity类的 11
 public static WindowsImpersonationContext ImpersonateUser(string strDomain,
public static WindowsImpersonationContext ImpersonateUser(string strDomain, 12
 string strLogin,
string strLogin, 13

14
 string strPwd,
string strPwd, 15

16
 LogonType logonType,
LogonType logonType, 17

18
 LogonProvider logonProvider);
LogonProvider logonProvider); 19

20
 附NetworkSecurity.cs源代码如下:
附NetworkSecurity.cs源代码如下: 21

22
 /*
/* 23
 * Author : TongWei
* Author : TongWei 24
 * Date : 2005-1-25
* Date : 2005-1-25 25
 * Rights : China Netwave Inc.@2005
* Rights : China Netwave Inc.@2005 26
 */
*/ 27

28
 using System;
using System; 29
 using System.Runtime.InteropServices;
using System.Runtime.InteropServices; 30
 using System.Security.Principal;
using System.Security.Principal; 31
 using System.Security.Permissions;
using System.Security.Permissions; 32

33
 namespace CNW.OMP.Common.Utility
namespace CNW.OMP.Common.Utility 34
 {
{ 35
 public enum LogonType : int
public enum LogonType : int 36
 {
{ 37
 /// <summary>
/// <summary> 38
 /// This logon type is intended for users who will be interactively using the computer, such as a user
/// This logon type is intended for users who will be interactively using the computer, such as a user 39
 /// being logged on by a terminal server, remote shell, or similar process. This logon type has the
/// being logged on by a terminal server, remote shell, or similar process. This logon type has the 40
 /// additional expense of caching logon information for disconnected operation, and is therefore
/// additional expense of caching logon information for disconnected operation, and is therefore 41
 /// inappropriate for some client/server applications, such as a mail server.
/// inappropriate for some client/server applications, such as a mail server. 42
 /// </summary>
/// </summary> 43
 LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_INTERACTIVE = 2, 44

45
 /// <summary>
/// <summary> 46
 /// This logon type is intended for high performance servers to authenticate clear text passwords.
/// This logon type is intended for high performance servers to authenticate clear text passwords. 47
 /// The LogonUser function does not cache credentials for this logon type.
/// The LogonUser function does not cache credentials for this logon type. 48
 /// </summary>
/// </summary> 49
 LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_NETWORK = 3, 50

51
 /// <summary>
/// <summary> 52
 /// This logon type is intended for batch servers, where processes may be executing on behalf of a user
/// This logon type is intended for batch servers, where processes may be executing on behalf of a user 53
 /// without their direct intervention; or for higher performance servers that process many clear-text
/// without their direct intervention; or for higher performance servers that process many clear-text 54
 /// authentication attempts at a time, such as mail or web servers. The LogonUser function does not cache
/// authentication attempts at a time, such as mail or web servers. The LogonUser function does not cache 55
 /// credentials for this logon type.
/// credentials for this logon type. 56
 /// </summary>
/// </summary> 57
 LOGON32_LOGON_BATCH = 4,
LOGON32_LOGON_BATCH = 4, 58

59
 /// <summary>
/// <summary> 60
 /// Indicates a service-type logon. The account provided must have the service privilege enabled.
/// Indicates a service-type logon. The account provided must have the service privilege enabled. 61
 /// </summary>
/// </summary> 62
 LOGON32_LOGON_SERVICE = 5,
LOGON32_LOGON_SERVICE = 5, 63

64
 /// <summary>
/// <summary> 65
 /// This logon type is intended for GINA DLLs logging on users who will be interactively using the computer.
/// This logon type is intended for GINA DLLs logging on users who will be interactively using the computer. 66
 /// This logon type allows a unique audit record to be generated that shows when the workstation was unlocked.
/// This logon type allows a unique audit record to be generated that shows when the workstation was unlocked. 67
 /// </summary>
/// </summary> 68
 LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_UNLOCK = 7, 69

70
 /// <summary>
/// <summary> 71
 /// Windows XP/2000: This logon type preserves the name and password in the authentication packages,
/// Windows XP/2000: This logon type preserves the name and password in the authentication packages, 72
 /// allowing the server to make connections to other network servers while impersonating the client.
/// allowing the server to make connections to other network servers while impersonating the client. 73
 /// This allows a server to accept clear text credentials from a client, call LogonUser, verify that
/// This allows a server to accept clear text credentials from a client, call LogonUser, verify that 74
 /// the user can access the system across the network, and still communicate with other servers.
/// the user can access the system across the network, and still communicate with other servers. 75
 /// </summary>
/// </summary> 76
 LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
LOGON32_LOGON_NETWORK_CLEARTEXT = 8, 77

78
 /// <summary>
/// <summary> 79
 /// Windows XP/2000: This logon type allows the caller to clone its current token and specify new credentials
/// Windows XP/2000: This logon type allows the caller to clone its current token and specify new credentials 80
 /// for outbound connections. The new logon session has the same local identity, but uses different credentials
/// for outbound connections. The new logon session has the same local identity, but uses different credentials 81
 /// for other network connections.
/// for other network connections. 82
 /// This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
/// This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider. 83
 /// </summary>
/// </summary> 84
 LOGON32_LOGON_NEW_CREDENTIALS = 9
LOGON32_LOGON_NEW_CREDENTIALS = 9 85
 };
}; 86

87
 public enum LogonProvider : int
public enum LogonProvider : int 88
 {
{ 89
 /// <summary>
/// <summary> 90
 /// Use the standard logon provider for the system. The default security provider is NTLM.
/// Use the standard logon provider for the system. The default security provider is NTLM. 91
 /// Windows XP: The default provider is negotiate, unless you pass NULL for the domain name and
/// Windows XP: The default provider is negotiate, unless you pass NULL for the domain name and 92
 /// the user name is not in UPN format. In this case the default provider is NTLM.
/// the user name is not in UPN format. In this case the default provider is NTLM. 93
 /// </summary>
/// </summary> 94
 LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_DEFAULT = 0, 95

96
 /// <summary>
/// <summary> 97
 /// Use the Windows NT 3.5 logon provider.
/// Use the Windows NT 3.5 logon provider. 98
 /// </summary>
/// </summary> 99
 LOGON32_PROVIDER_WINNT35 = 1,
LOGON32_PROVIDER_WINNT35 = 1, 100

101
 /// <summary>
/// <summary> 102
 /// Use the NTLM logon provider.
/// Use the NTLM logon provider. 103
 /// </summary>
/// </summary> 104
 LOGON32_PROVIDER_WINNT40 = 2,
LOGON32_PROVIDER_WINNT40 = 2, 105

106
 /// <summary>
/// <summary> 107
 /// Windows XP/2000: Use the negotiate logon provider.
/// Windows XP/2000: Use the negotiate logon provider. 108
 /// </summary>
/// </summary> 109
 LOGON32_PROVIDER_WINNT50 = 3
LOGON32_PROVIDER_WINNT50 = 3 110
 };
}; 111

112
 class SecuUtil32
class SecuUtil32 113
 {
{ 114
 [DllImport("advapi32.dll", SetLastError=true)]
[DllImport("advapi32.dll", SetLastError=true)] 115
 public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, 116
 int dwLogonType, int dwLogonProvider, ref IntPtr TokenHandle);
int dwLogonType, int dwLogonProvider, ref IntPtr TokenHandle); 117

118
 [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
[DllImport("kernel32.dll", CharSet=CharSet.Auto)] 119
 public extern static bool CloseHandle(IntPtr handle);
public extern static bool CloseHandle(IntPtr handle); 120

121
 [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] 122
 public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, 123
 int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); 124
 }
} 125

126
 public class NetworkSecurity
public class NetworkSecurity 127
 {
{ 128
 public NetworkSecurity()
public NetworkSecurity() 129
 {
{ 130
 //
// 131
 // TODO: Add constructor logic here
// TODO: Add constructor logic here 132
 //
// 133
 }
} 134

135
 /// <summary>
/// <summary> 136
 /// The ImpersonateUser function attempts to log a user on to the local computer.
/// The ImpersonateUser function attempts to log a user on to the local computer. 137
 /// The local computer is the computer from which ImpersonateUser was called.
/// The local computer is the computer from which ImpersonateUser was called. 138
 /// You cannot use ImpersonateUser to log on to a remote computer.
/// You cannot use ImpersonateUser to log on to a remote computer. 139
 /// You specify the user with a user name and domain, and authenticate the user with a clear-text password.
/// You specify the user with a user name and domain, and authenticate the user with a clear-text password. 140
 /// If the function succeeds, you receive a handle to a token that represents the logged-on user.
/// If the function succeeds, you receive a handle to a token that represents the logged-on user. 141
 /// You can then use this token handle to impersonate the specified user, or in most cases,
/// You can then use this token handle to impersonate the specified user, or in most cases, 142
 /// to create a process running in the context of the specified user.
/// to create a process running in the context of the specified user. 143
 /// </summary>
/// </summary> 144
 /// <param name="strDomain">
/// <param name="strDomain"> 145
 /// specifies the name of the domain or server whose account database contains the strLogin account.
/// specifies the name of the domain or server whose account database contains the strLogin account. 146
 /// </param>
/// </param> 147
 /// <param name="strLogin">specifies the name of the user.</param>
/// <param name="strLogin">specifies the name of the user.</param> 148
 /// <param name="strPwd">specifies the clear-text password for the user account specified by strLogin.</param>
/// <param name="strPwd">specifies the clear-text password for the user account specified by strLogin.</param> 149
 /// <param name="logonType">Specifies the type of logon operation to perform.</param>
/// <param name="logonType">Specifies the type of logon operation to perform.</param> 150
 /// <param name="logonProvider">Specifies the logon provider.</param>
/// <param name="logonProvider">Specifies the logon provider.</param> 151
 /// <example>
/// <example> 152
 /// //Add System.Security.dll
/// //Add System.Security.dll 153
 /// //using System.Security.Principal;
/// //using System.Security.Principal; 154
 ///
/// 155
 /// string strDomain=ConfigurationSettings.AppSettings["mSALoginDomainName"];
/// string strDomain=ConfigurationSettings.AppSettings["mSALoginDomainName"]; 156
 /// string strUser=ConfigurationSettings.AppSettings["mSALoginDomainUser"];
/// string strUser=ConfigurationSettings.AppSettings["mSALoginDomainUser"]; 157
 /// string strPassword=ConfigurationSettings.AppSettings["mSALoginDomainPassword"];
/// string strPassword=ConfigurationSettings.AppSettings["mSALoginDomainPassword"]; 158
 ///
/// 159
 /// WindowsImpersonationContext impContext = null;
/// WindowsImpersonationContext impContext = null; 160
 /// try
/// try 161
 /// {
/// { 162
 /// impContext = NetworkSecurity.ImpersonateUser(strDomain,strUser,strPassword,
/// impContext = NetworkSecurity.ImpersonateUser(strDomain,strUser,strPassword, 163
 /// LogonType.LOGON32_LOGON_SERVICE,
/// LogonType.LOGON32_LOGON_SERVICE, 164
 /// LogonProvider.LOGON32_PROVIDER_DEFAULT);
/// LogonProvider.LOGON32_PROVIDER_DEFAULT); 165
 /// }
/// } 166
 /// catch
/// catch 167
 /// {
/// { 168
 ///
/// 169
 /// }
/// } 170
 ///
/// 171
 /// //work under this logined user
/// //work under this logined user 172
 ///
/// 173
 /// impContext.Undo();
/// impContext.Undo(); 174
 /// </example>
/// </example> 175
 /// <returns>
/// <returns> 176
 /// </returns>
/// </returns> 177
 public static WindowsImpersonationContext ImpersonateUser(string strDomain,
public static WindowsImpersonationContext ImpersonateUser(string strDomain, 178
 string strLogin,
string strLogin, 179
 string strPwd,
string strPwd, 180
 LogonType logonType,
LogonType logonType, 181
 LogonProvider logonProvider)
LogonProvider logonProvider) 182
 {
{ 183
 // Initialize tokens
// Initialize tokens 184
 IntPtr tokenHandle = new IntPtr(0);
IntPtr tokenHandle = new IntPtr(0); 185
 IntPtr dupeTokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0); 186
 tokenHandle = IntPtr.Zero;
tokenHandle = IntPtr.Zero; 187
 dupeTokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero; 188

189
 // If domain name was blank, assume local machine
// If domain name was blank, assume local machine 190
 if (strDomain == "")
if (strDomain == "") 191
 strDomain = System.Environment.MachineName;
strDomain = System.Environment.MachineName; 192

193
 try
try 194
 {
{ 195
 const int SecurityImpersonation = 2;
const int SecurityImpersonation = 2; 196

197
 // Call LogonUser to obtain a handle to an access token.
// Call LogonUser to obtain a handle to an access token. 198
 bool returnValue = SecuUtil32.LogonUser(
bool returnValue = SecuUtil32.LogonUser( 199
 strLogin,
strLogin, 200
 strDomain,
strDomain, 201
 strPwd,
strPwd, 202
 (int)logonType,
(int)logonType, 203
 (int)logonProvider,
(int)logonProvider, 204
 ref tokenHandle);
ref tokenHandle); 205

206
 // Did impersonation fail?
// Did impersonation fail? 207
 if (false == returnValue)
if (false == returnValue) 208
 {
{ 209
 int ret = Marshal.GetLastWin32Error();
int ret = Marshal.GetLastWin32Error(); 210
 // Throw the exception show the reason why LogonUser failed
// Throw the exception show the reason why LogonUser failed 211
 string strErr = String.Format("LogonUser failed with error code : {0}", ret);
string strErr = String.Format("LogonUser failed with error code : {0}", ret); 212
 throw new ApplicationException(strErr, null);
throw new ApplicationException(strErr, null); 213
 }
} 214

215
 // Get identity before impersonation
// Get identity before impersonation 216
 bool retVal = SecuUtil32.DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
bool retVal = SecuUtil32.DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle); 217

218
 // Did DuplicateToken fail?
// Did DuplicateToken fail? 219
 if (false == retVal)
if (false == retVal) 220
 {
{ 221
 // Close existing handle
// Close existing handle 222
 SecuUtil32.CloseHandle(tokenHandle);
SecuUtil32.CloseHandle(tokenHandle); 223
 // Throw the exception show the reason why DuplicateToken failed
// Throw the exception show the reason why DuplicateToken failed 224
 throw new ApplicationException("Failed to duplicate token", null);
throw new ApplicationException("Failed to duplicate token", null); 225
 }
} 226

227
 // Create new identity using new primary token
// Create new identity using new primary token 228
 // The token that is passed to the following constructor must
// The token that is passed to the following constructor must 229
 // be a primary token in order to use it for impersonation.
// be a primary token in order to use it for impersonation. 230
 WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle); 231
 WindowsImpersonationContext impersonatedUser = newId.Impersonate();
WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 232

233
 return impersonatedUser;
return impersonatedUser; 234
 }
} 235
 catch (Exception ex)
catch (Exception ex) 236
 {
{ 237
 throw new ApplicationException(ex.Message, ex);
throw new ApplicationException(ex.Message, ex); 238
 }
} 239
 finally
finally 240
 {
{ 241
 // Close handle
// Close handle 242
 if (tokenHandle != IntPtr.Zero)
if (tokenHandle != IntPtr.Zero) 243
 SecuUtil32.CloseHandle(tokenHandle);
SecuUtil32.CloseHandle(tokenHandle); 244
 if (dupeTokenHandle != IntPtr.Zero)
if (dupeTokenHandle != IntPtr.Zero) 245
 SecuUtil32.CloseHandle(dupeTokenHandle);
SecuUtil32.CloseHandle(dupeTokenHandle); 246
 }
} 247
 }
} 248
 }
} 249
 }
} 250
 
 251
 
 252

 <%@ Page Language="C#"%>
<%@ Page Language="C#"%> <%@ Import Namespace = "System.Web" %>
<%@ Import Namespace = "System.Web" %> <%@ Import Namespace = "System.Web.Security" %>
<%@ Import Namespace = "System.Web.Security" %> <%@ Import Namespace = "System.Security.Principal" %>
<%@ Import Namespace = "System.Security.Principal" %> <%@ Import Namespace = "System.Runtime.InteropServices" %>
<%@ Import Namespace = "System.Runtime.InteropServices" %>
 <script runat=server>
<script runat=server> public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_LOGON_INTERACTIVE = 2; public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_PROVIDER_DEFAULT = 0;
 WindowsImpersonationContext impersonationContext;
WindowsImpersonationContext impersonationContext;
 [DllImport("advapi32.dll")]
[DllImport("advapi32.dll")] public static extern int LogonUserA(String lpszUserName,
public static extern int LogonUserA(String lpszUserName, String lpszDomain,
    String lpszDomain, String lpszPassword,
    String lpszPassword, int dwLogonType,
    int dwLogonType, int dwLogonProvider,
    int dwLogonProvider, ref IntPtr phToken);
    ref IntPtr phToken); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern int DuplicateToken(IntPtr hToken,
public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel,
    int impersonationLevel, ref IntPtr hNewToken);
    ref IntPtr hNewToken);
 [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool RevertToSelf();
public static extern bool RevertToSelf();
 [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
[DllImport("kernel32.dll", CharSet=CharSet.Auto)] public static extern  bool CloseHandle(IntPtr handle);
public static extern  bool CloseHandle(IntPtr handle);
 public void Page_Load(Object s, EventArgs e)
public void Page_Load(Object s, EventArgs e) {
{ if(impersonateValidUser("username", "domain", "password"))
    if(impersonateValidUser("username", "domain", "password")) {
    { //Insert your code that runs under the security context of a specific user here.
        //Insert your code that runs under the security context of a specific user here. undoImpersonation();
        undoImpersonation(); }
    } else
    else {
    { //Your impersonation failed. Therefore, include a fail-safe mechanism here.
        //Your impersonation failed. Therefore, include a fail-safe mechanism here. }
    } }
}
 private bool impersonateValidUser(String userName, String domain, String password)
private bool impersonateValidUser(String userName, String domain, String password) {
{ WindowsIdentity tempWindowsIdentity;
    WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero;
    IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;
 if(RevertToSelf())
    if(RevertToSelf()) {
    { if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
        if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
            LOGON32_PROVIDER_DEFAULT, ref token) != 0) {
        { if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
            if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) {
            { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); impersonationContext = tempWindowsIdentity.Impersonate();
                impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null)
                if (impersonationContext != null) {
                { CloseHandle(token);
                    CloseHandle(token); CloseHandle(tokenDuplicate);
                    CloseHandle(tokenDuplicate); return true;
                    return true; }
                } }
            } }
        } }
    } if(token!= IntPtr.Zero)
    if(token!= IntPtr.Zero) CloseHandle(token);
        CloseHandle(token); if(tokenDuplicate!=IntPtr.Zero)
    if(tokenDuplicate!=IntPtr.Zero) CloseHandle(tokenDuplicate);
        CloseHandle(tokenDuplicate); return false;
    return false; }
}
 private void undoImpersonation()
private void undoImpersonation() {
{ impersonationContext.Undo();
    impersonationContext.Undo(); }
} </script>
</script> 
                    
                     
                    
                 
                    
                



 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号