繁体   English   中英

Windows服务中的模拟

[英]Impersonation in Windows Service

我有一个Windows服务,它通过来自不同服务器的SQL连接字符串来获取数据集。 我需要模拟可以访问此SQL Server数据库的特定用户帐户。 如果我将它构建为控制台应用程序,代码可以找到,但是Windows服务会让事情变得混乱。

当构建为Windows服务时,无论是模拟,服务都会尝试使用错误指定的计算机帐户(错误)进行连接和身份验证:

无法打开登录请求的数据库\\“DATABASE \\”。 登录失败。 用户'DOMAIN \\ MACHINENAME'登录失败。

使用这段代码我使用模仿类:

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public DataSet GetDataSetSQL(string pSQL)
    {
        DataSet ds = null;
        DbDataAdapter adapter = null;
        try
        {
            using (impers = new Impersonator(impers_uname, impers_domain, impers_password))
            {
                /// Create connection
                using (DbConnection conn = this.factory.CreateConnection())
                {
                    conn.ConnectionString = this.connectionString;

                    /// Create Command
                    using (DbCommand cmd = conn.CreateCommand())
                    {
                        cmd.Connection = conn;
                        cmd.CommandType = CommandType.Text;
                        cmd.CommandText = pSQL;

                        adapter = this.factory.CreateDataAdapter();
                        adapter.SelectCommand = cmd;

                        ds = new DataSet();
                        adapter.Fill(ds);
                    }
                }
            }
        }
        finally
        {
            if (adapter != null) adapter = null;
        }
        return ds;
    }

这是我获得令牌的地方:

if (LogonUser(
                    userName,
                    domain,
                    password,
                    LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT,
                    ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        impersonationContext = tempWindowsIdentity.Impersonate();
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

我可以在用户帐户下运行Windows服务,但我希望具有更高级别的粒度和可移植性。

任何人都有任何想法应用程序和Windows服务之间的模仿是如何不同的?

编辑

新的枚举和logonuser函数调用

public enum LogonType
    {
        LOGON32_LOGON_INTERACTIVE = 2,
        LOGON32_LOGON_NETWORK = 3,
        LOGON32_LOGON_BATCH = 4,
        LOGON32_LOGON_SERVICE = 5,
        LOGON32_LOGON_UNLOCK = 7,
        LOGON32_LOGON_NETWORK_CLEARTEXT = 8, // Win2K or higher
        LOGON32_LOGON_NEW_CREDENTIALS = 9 // Win2K or higher
    };

    public enum LogonProvider
    {
        LOGON32_PROVIDER_DEFAULT = 0,
        LOGON32_PROVIDER_WINNT35 = 1,
        LOGON32_PROVIDER_WINNT40 = 2,
        LOGON32_PROVIDER_WINNT50 = 3
    };

if (LogonUser(
                    userName,
                    domain,
                    password,
                    (int)LogonType.LOGON32_LOGON_NEW_CREDENTIALS,
                    (int)LogonProvider.LOGON32_PROVIDER_WINNT50,
                    ref token) != 0)

关于LogonUser函数的第4个参数,您使用的是LOGON32_LOGON_INTERACTIVE。

此登录类型适用于将以交互方式使用计算机的用户,例如由终端服务器,远程shell或类似进程登录的用户。 但Windows服务不属于这一类,所以我应该使用LOGON32_LOGON_SERVICE代替。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM