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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252
















































































【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix