一个在.net下进行用户模拟的类

2003-10-24 by 开心就好

实质上是通过WindowsIdentity.Impersonate()的方法,其中需要调用Win API来获得活用的Handle,用法其实很简单,因为在自己的代码中需要用到,就稍微封装了一下:

?public class IdentityImpersonation {

??[DllImport("advapi32.dll", SetLastError=true)]
??public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
???int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

??[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
??public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
???int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

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

??// 要模拟的用户的用户名、密码、域(机器名)
??private String _sImperUsername;
??private String _sImperPassword;
??private String _sImperDomain;
??// 记录模拟上下文
??private WindowsImpersonationContext _imperContext;
??private IntPtr _adminToken;
??private IntPtr _dupeToken;
??// 是否已停止模拟
??private Boolean _bClosed;

??public IdentityImpersonation(String impersonationUsername, String impersonationPassword, String impersonationDomain) {
???_sImperUsername = impersonationUsername;
???_sImperPassword = impersonationPassword;
???_sImperDomain = impersonationDomain;

???_adminToken = IntPtr.Zero;
???_dupeToken = IntPtr.Zero;
???_bClosed = true;
??}

??\~IdentityImpersonation() {
???if(! _bClosed) {
????StopImpersonation();
???}
??}

??public Boolean BeginImpersonate() {
?
???Boolean bLogined = LogonUser(_sImperUsername, _sImperDomain, _sImperPassword, 2, 0, ref _adminToken);
???
???if(! bLogined) {
????return false;
???}

???Boolean bDuped = DuplicateToken(_adminToken, 2, ref _dupeToken);

???if(! bDuped) {
????return false;
???}

???WindowsIdentity fakeId = new WindowsIdentity(_dupeToken);
???_imperContext = fakeId.Impersonate();

???_bClosed = false;

???return true;
??}

??public void StopImpersonate() {
???_imperContext.Undo();
???CloseHandle(_dupeToken);
???CloseHandle(_adminToken);
???_bClosed = true;
??}
?}

?

使用示例:

IdentityImpersonation imper = new IdentityImpersonation("tsg", "123456", "webreal");
imper.BeginImpersonation();
// ...
imper.StopImpersonation();


Comments