模拟整个应用程序生命周期
本文关键字:生命 周期 应用程序 模拟 | 更新日期: 2023-09-27 17:51:12
我一直在使用这个链接来设置模拟。我有很多方法,我需要冒充所有的人。
- 我是否必须在每个方法调用或存在周围添加使用代码控件的整个生命周期设置模拟的方法应用程序?
- 我在下面冒充本地管理员我的代码有任何缺陷或安全隐患吗?
- 是下面LOGON32_LOGON_NEW_CREDENTIALS值2正确(它按预期工作)
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);
}
}
}
}
有很多方法可以做到这一点,而不是只有一种正确的方法。一种方法可能是将想要模拟的方法作为委托传递给某种ImpersonatedContext类,该类将在您的Impersonator作用域中包装调用。这也将把所有的逻辑从按钮单击事件处理程序中移开,这在体系结构上也不是最好的方法。
关于你的安全问题,到目前为止你是直接指定用户名和密码。如果伊芙要反编译你的代码,她就能看到密码。也许应该让用户指定管理员密码?
我也一直在使用示例代码,它对我来说工作得很好。我认为LOGON32_LOGON_NEW_CREDENTIALS很好。你可以在这里阅读更多关于不同模式的信息(LogonUser)
我想这是一个简单的例子,就像这样。您传递的委托接受一个对象,并以布尔值的形式返回成功值。你可以根据自己的需要修改。
public class ImpersonationContext {
public delegate bool ImpersonationDel(object obj);
public bool Invoke(ImpersonationDel del){
using (new Impersonation("LocalHost", "test", "test")){
return del.Invoke();
}
}
}