【问题标题】:Impersonate for entire application lifecycle模拟整个应用程序生命周期
【发布时间】:2014-03-20 20:56:54
【问题描述】:

我一直在使用这个link 来设置模拟。我有很多方法,我需要为所有方法模仿。

  1. 我必须在每个方法调用周围添加使用代码吗? 一种为整个生命周期设置模拟的方法 应用 ?
  2. 我在下面冒充本地管理员 - 是 我的代码有任何缺陷或安全隐患吗?
  3. 是 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

标签: c# impersonation


【解决方案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();
        }
    }
}

【讨论】:

  • 嗨安德烈亚斯,你能提供一个关于你的第一段的代码示例吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多