模拟整个应用程序生命周期
Posted
技术标签:
【中文标题】模拟整个应用程序生命周期【英文标题】:Impersonate for entire application lifecycle 【发布时间】:2014-03-20 20:56:54 【问题描述】:我一直在使用这个link 来设置模拟。我有很多方法,我需要为所有方法模仿。
-
我必须在每个方法调用周围添加使用代码吗?
一种为整个生命周期设置模拟的方法
应用 ?
我在下面冒充本地管理员 - 是
我的代码有任何缺陷或安全隐患吗?
是 LOGON32_LOGON_NEW_CREDENTIALS 值 2 正确(它按预期工作)
c#代码
private void buttonUsingImpersonation_Click(object sender, EventArgs e)
try
using (new Impersonation("LocalHost", "test", "test"))
// do whatever you want
string fileName = System.IO.Path.GetRandomFileName();
String pathString = System.IO.Path.Combine(FolderPath, fileName);
.
if (!System.IO.File.Exists(pathString))
using (System.IO.FileStream fs = System.IO.File.Create(pathString))
for (byte i = 0; i < 100; i++)
fs.WriteByte(i);
else
MessageBox.Show("File already exists " + fileName);
return;
catch (Exception ex)
// If exception happens, it will be returned here
MessageBox.Show("Error " + MethodBase.GetCurrentMethod().Name + " " + ex.ToString());
类
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;
namespace ImpersonationDemo
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class Impersonation : IDisposable
private readonly SafeTokenHandle _handle;
private readonly WindowsImpersonationContext _context;
const int LOGON32_LOGON_NEW_CREDENTIALS = 2;
public Impersonation(string domain, string username, string password)
var ok = LogonUser(username, domain, password,
LOGON32_LOGON_NEW_CREDENTIALS, 0, out this._handle);
if (!ok)
var errorCode = Marshal.GetLastWin32Error();
throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code 0.", errorCode));
this._context = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
public void Dispose()
this._context.Dispose();
this._handle.Dispose();
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
private SafeTokenHandle()
: base(true)
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
return CloseHandle(handle);
【问题讨论】:
我相信 LOGON32_LOGON_NEW_CREDENTIALS 是 9,而不是 2; 2 表示 LOGON32_LOGON_INTERACTIVE 【参考方案1】:有很多方法可以做到这一点,但没有一种正确的方法。一种方法可能是将您希望模拟为委托的方法传递给某种 ImpersonatedContext 类,该类会将调用包装在您的 Impersonator 范围内。这也会将所有逻辑从按钮单击事件处理程序中移开,这在架构上也不是最好的方法。
关于您关于安全性的问题,那么到目前为止,您正在直接指定用户名和密码。如果 Eve 要反编译您的代码,她将能够看到密码。也许你应该让用户指定管理员密码?
我也一直在使用示例代码,它对我来说效果很好。我认为 LOGON32_LOGON_NEW_CREDENTIALS 很好。您可以阅读更多关于不同模式的信息here (LogonUser)
更新 我想一个快速的例子是这样的。您传递的委托接受一个对象,并返回一个成功值作为布尔值。您可以修改它以满足您的需要。
public class ImpersonationContext
public delegate bool ImpersonationDel(object obj);
public bool Invoke(ImpersonationDel del)
using (new Impersonation("LocalHost", "test", "test"))
return del.Invoke();
【讨论】:
嗨安德烈亚斯,你能提供一个关于你的第一段的代码示例吗?以上是关于模拟整个应用程序生命周期的主要内容,如果未能解决你的问题,请参考以下文章