模拟整个应用程序生命周期

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();
        
    

【讨论】:

嗨安德烈亚斯,你能提供一个关于你的第一段的代码示例吗?

以上是关于模拟整个应用程序生命周期的主要内容,如果未能解决你的问题,请参考以下文章

小程序的生命周期

一个简单扫描应用彻底明白Android 生命周期

C语言中,哪种存储类的作用域与生命周期是不一致的?

Vue 啥是生命周期

vue生命周期的基础部分

浅谈Vue的生命周期模型