【问题标题】:C# How to change user context in app running on systemC#如何在系统上运行的应用程序中更改用户上下文
【发布时间】:2018-04-07 04:19:24
【问题描述】:

我有一个与系统用户一起运行的应用程序。我需要应用程序中的一些代码在用户上下文(与用户本身)上运行。例如,我需要在用户上下文中使用 webclient,因为这样我的防火墙可以识别用户名,但后来我需要运行一些其他代码。在系统上下文中运行 exe(使用系统用户),因为我需要权限。

有没有办法做到这一点?

谢谢!!!

【问题讨论】:

  • 你所描述的毫无意义。
  • 抱歉,如果没有很好的解释。在我的工作中,我们有一个通过 kerberos 进行身份验证的代理,以让用户浏览互联网,如果用户系统尝试访问互联网,则访问被拒绝。因此,为此我需要在用户上下文中运行它,但稍后在程序中我有一个需要以管理员权限运行 exe 的功能(经典用户在他自己的机器上不是管理员)所以这就是我需要做的。跨度>

标签: c# security system


【解决方案1】:

我已经使用这段代码来模拟某些操作

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;
using NLog;
namespace Core.Impersonation
{
    public class ImpersonatedUser : IDisposable
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        IntPtr userHandle;
        WindowsImpersonationContext impersonationContext;
        public ImpersonatedUser(string user, string domain, string password)
        {
            logger.Debug("Impersonating user: " + domain + @"\" + user);
            userHandle = IntPtr.Zero;
            bool loggedOn = LogonUser(
                user,
                domain,
                password,
                LogonType.Interactive,
                LogonProvider.Default,
                out userHandle);

            if (!loggedOn)
                throw new Win32Exception(Marshal.GetLastWin32Error());

            // Begin impersonating the user
            impersonationContext = WindowsIdentity.Impersonate(userHandle);
        }

        public void Dispose()
        {
            if (userHandle != IntPtr.Zero)
            {
                CloseHandle(userHandle);
                userHandle = IntPtr.Zero;
                impersonationContext.Undo();
                logger.Debug("Finished Impersonating user");
            }
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool LogonUser(
            string lpszUsername,
            string lpszDomain,
            string lpszPassword,
            LogonType dwLogonType,
            LogonProvider dwLogonProvider,
            out IntPtr phToken
            );

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr hHandle);

        enum LogonType : int
        {
            Interactive = 2,
            Network = 3,
            Batch = 4,
            Service = 5,
            NetworkCleartext = 8,
            NewCredentials = 9,
        }

        enum LogonProvider : int
        {
            Default = 0,
        }
    }
}

然后用法:

using (var i = new ImpersonatedUser("someLogin", "someDomain", "thePassword"))
{
    var u = System.Environment.UserName;
}

【讨论】:

  • 谢谢!有没有办法使用登录上下文的用户发送用户凭据?。
  • 如果我使用这个:using (var i = new ImpersonatedUser("user", "domain", "pass")) { Process startInfo = new Process(); startInfo.StartInfo.FileName = @"c:\windows\system32\cmd.exe"; startInfo.Start(); startInfo.WaitForExit(); var u = System.Environment.UserName; Dispose(); } CMD 不会与预期的用户一起启动。
  • 如果您想以不同的用户身份启动进程,请在 ProcessStartinfo 中设置适当的设置。有关示例,请参见 here
猜你喜欢
  • 2020-04-10
  • 1970-01-01
  • 2012-01-31
  • 2013-10-03
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多