Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 安装证书时模拟用户_C# - Fatal编程技术网

C# 安装证书时模拟用户

C# 安装证书时模拟用户,c#,C#,模拟管理员用户将.cer(证书文件)文件安装到本地计算机时出现问题…正在为CurrentUser work perfekt安装 我总是收到错误消息“拒绝访问” 使用以下代码进行模拟: using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Security.Principal; public class ImpersonatedUser : IDisposa

模拟管理员用户将.cer(证书文件)文件安装到本地计算机时出现问题…正在为CurrentUser work perfekt安装

我总是收到错误消息“拒绝访问”

使用以下代码进行模拟:

using System;

using System.ComponentModel;

using System.Runtime.InteropServices;

using System.Security.Principal;

public class ImpersonatedUser : IDisposable
{

    IntPtr userHandle;

    WindowsImpersonationContext impersonationContext;



    public ImpersonatedUser(string domain,string user, string password)
    {

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

        }

    }



    [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,
        WINNT50 = 3,

    }
这是证书安装方法:

private static void InstallCertificate(string cerFileName, StoreName storeName)
        {
            LoginInfo loginInfo = new LoginInfo();
            X509Certificate2 certificate = new X509Certificate2(cerFileName);
            X509Store store = new X509Store(storeName, StoreLocation.LocalMachine);
            try
            {

                    store.Open(OpenFlags.ReadWrite);
                    store.Add(certificate);
                    store.Close();

            }
            catch (Exception e)
            {
                string CertName = Path.GetFileName(cerFileName);
                string source = e.Source.ToString();
                string message = e.Message.ToString();
                string messagetext = string.Format("Certificate installation \"{0}\" was not succsessfull Error: {1}", CertName, message);
                StringBuilder messagestring = new StringBuilder();
                messagestring.Append(source);
                messagestring.Append(message);
                MessageBox.Show(messagetext, "Install Certificate Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
这就是我在ImpersonatedUser中调用方法的方式

using (new ImpersonatedUser(loginInfo.DomainName, loginInfo.UserName, loginInfo.Password))
                            {


                                MessageBox.Show(WindowsIdentity.GetCurrent().Name);
                                InstallCertificate(certpath, StoreName.TrustedPublisher);

                }

MS有一个很好的帮助页面,例如:

代码之间的明显区别在于,您没有在函数中包含
[PermissionSetAttribute(SecurityAction.Demand,Name=“FullTrust”)]
限定符。如果这是一个库的一部分,您也需要对整个库执行此操作


我假设您登录的用户具有安装证书的权限——请确保您的用户具有这些权限。

以下是我用于模拟服务帐户的代码,经证明运行良好:

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;
using System.Configuration;

namespace ImpersonationUtil
{
    /// <summary>
    /// Facilitates impersonation of a Windows User.
    /// </summary>
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class Impersonation : IDisposable
    {
        public string Environment { get; set; }

        public string UserName { get; set; }

        public string Password { get; set; }

        public string DomainName { get; set; }

        public enum LogonType
        {
            Interactive = 2,
            Network = 3,
            Batch = 4,
            Service = 5,
            Unlock = 7,
            NetworkClearText = 8,
            NewCredentials = 9
        }

        public enum LogonProvider
        {
            Default = 0,
            WinNT35 = 1,
            WinNT40 = 2,
            WinNT50 = 3
        }

        /// <summary>
        /// Windows Token.
        /// </summary>
        private readonly SafeTokenHandle _handle;

        /// <summary>
        /// The impersonated User.
        /// </summary>
        private WindowsImpersonationContext impersonatedUser;

        public Impersonation()
        {
        }

        /// <summary>
        /// Initializes a new instance of the Impersonation class. Provides domain, user name, and password for impersonation.
        /// </summary>
        /// <param name="domainName">Domain name of the impersonated user.</param>
        /// <param name="userName">Name of the impersonated user.</param>
        /// <param name="password">Password of the impersonated user.</param>
        /// <remarks>
        /// Uses the unmanaged LogonUser function to get the user token for
        /// the specified user, domain, and password.
        /// </remarks>
        public Impersonation(AccountCredentials credentials)
        {            
            string[] splitName = WindowsIdentity.GetCurrent().Name.Split('\\');
            string name = (splitName.Length > 0) ? splitName[0] : null;

            LogonType logonType = LogonType.Interactive;
            LogonProvider logonProvider = LogonProvider.Default;

            if (name != credentials.Domain)
            {
                logonType = LogonType.NewCredentials;
                logonProvider = LogonProvider.WinNT50;
            }

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(
                                credentials.UserName,
                                credentials.Domain,
                                credentials.Password,
                                (int)logonType,
                                (int)logonProvider,
                                out this._handle);

            if (false == returnValue)
            {
                // Something went wrong.
                int ret = Marshal.GetLastWin32Error();
                throw new System.ComponentModel.Win32Exception(ret);
            }

            this.impersonatedUser = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());    
        }

        /// <summary>
        /// Initializes a new instance of the Impersonation class. Provide domain, user name, and password for impersonation.
        /// </summary>
        /// <param name="domainName">Domain name of the impersonated user.</param>
        /// <param name="userName">Name of the impersonated user.</param>
        /// <param name="password">Password of the impersonated user.</param>
        /// <remarks>
        /// Uses the unmanaged LogonUser function to get the user token for
        /// the specified user, domain, and password.
        /// </remarks>
        public Impersonation(string domainName, string userName, string password)
        {
            string[] splitName = WindowsIdentity.GetCurrent().Name.Split('\\');
            string name = (splitName.Length > 0) ? splitName[0] : null;

            LogonType logonType = LogonType.Interactive;
            LogonProvider logonProvider = LogonProvider.Default;

            if (name != domainName)
            {
                logonType = LogonType.NewCredentials;
                logonProvider = LogonProvider.WinNT50;
            }

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(
                                userName,
                                domainName,
                                password,
                                (int)logonType,
                                (int)logonProvider,
                                out this._handle);

            if (false == returnValue)
            {
                // Something went wrong.
                int ret = Marshal.GetLastWin32Error();
                throw new System.ComponentModel.Win32Exception(ret);
            }

            this.impersonatedUser = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
        }

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

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern bool CloseHandle(IntPtr handle);

        public void Dispose()
        {
            this.impersonatedUser.Dispose();
            this._handle.Dispose();
        }

        private static string[] GetAccountInfo(string accountInfo)
        {
            return accountInfo.Split(' ');
        }
    }

    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);
        }
    }
}
用法示例:

AccountCredentials credentials = new AccountCredentials("user", "password", "domain");
using (new Impersonation(credentials))
{
    // do work under the impersonated user
}

需要注意的重要一点是,在尝试模拟与活动域不在同一域中的帐户时,必须使用正确的登录类型和登录提供程序。我检查此项并在模拟构造函数中自动分配正确的登录类型和登录提供程序。

我打赌用户访问列表问题和权限提升…这是您的答案。.我实现了您的类,但仍然拒绝访问。奇怪的是,如果我执行AccountCredentials=new AccountCredentials(loginInfo.UserName、loginInfo.Password、loginInfo.DomainName);使用(新模拟(凭据)){//在模拟用户MessageBox.Show(WindowsIdentity.GetCurrent().Groups.ToString()下工作);安装证书(certpath,StoreName.TrustedPublisher);}
AccountCredentials credentials = new AccountCredentials("user", "password", "domain");
using (new Impersonation(credentials))
{
    // do work under the impersonated user
}