gpt4 book ai didi

c# - 从非域计算机连接到域 SQL Server 2005

转载 作者:太空狗 更新时间:2023-10-29 18:15:34 25 4
gpt4 key购买 nike

几天前我问了一个问题 ( Access to SQL Server 2005 from a non-domain machine using Windows authentication ),得到了一些有趣但不可用的建议。我想再问一遍这个问题,但要明确我的限制是什么:

我有一个 Windows 域,其中一台计算机运行 SQL Server 2005,并且配置为仅支持 Windows 身份验证。我想在同一网络但不在域中的计算机上运行 C# 客户端应用程序,并访问 SQL Server 2005 实例上的数据库。

我不能在任何一台机器上创建或修改操作系统或 SQL Server 用户,我不能对权限或模拟进行任何更改,我不能使用 runas。

我知道我可以编写可以仅使用以下四个参数连接到 SQL Server 数据库的 Perl 和 Java 应用程序:服务器名称、数据库名称、用户名(格式为域\用户)和密码。

在 C# 中,我尝试了各种方法:

string connectionString = "Data Source=server;Initial Catalog=database;User Id=domain\user;Password=password";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();

并尝试将集成安全性设置为 true 和 false,但似乎没有任何效果。我想做的事情在 C# 中根本不可能吗?

感谢您的帮助,马丁

最佳答案

我在编写一个工具时遇到了类似的问题,该工具需要在一个域的机器上运行,并使用受信任的连接在另一个域的 SQL 服务器上进行身份验证。我能找到的有关该主题的所有内容都表明无法完成。相反,您必须加入域、使用 SQL 身份验证、参与一些称为 Kerberos 的小程序,或者让您的网络人员建立信任关系,仅举几例。

我知道我可以使用 RUNAS 以某种方式让它工作,因为我已经用 SSMS 证明了这一点:

C:\WINDOWS\system32\runas.exe /netonly /savecred /user:megacorp\joe.bloggs "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\SqlWb.exe"

/netonly 标志允许我使用本地凭据执行 exe 并使用远程凭据访问网络,我想,无论如何我从远程服务器获得了我期望的结果集。问题是 runas 命令使得调试应用程序变得非常困难,而且味道也不好。

最终我在 the code project 上找到了这篇文章这是在谈论对 Active Directory 进行身份验证,这是进行模拟的主要类:

    using System;    using System.Runtime.InteropServices;  // DllImport    using System.Security.Principal; // WindowsImpersonationContext    namespace TestApp    {        class Impersonator        {            // group type enum            enum SECURITY_IMPERSONATION_LEVEL : int            {                SecurityAnonymous = 0,                SecurityIdentification = 1,                SecurityImpersonation = 2,                SecurityDelegation = 3            }            // obtains user token            [DllImport("advapi32.dll", SetLastError = true)]            static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,                int dwLogonType, int dwLogonProvider, ref IntPtr phToken);            // closes open handes returned by LogonUser            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]            extern static bool CloseHandle(IntPtr handle);            // creates duplicate token handle            [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]            extern static bool DuplicateToken(IntPtr ExistingTokenHandle,                int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);            WindowsImpersonationContext newUser;            ///             /// Attempts to impersonate a user.  If successful, returns             /// a WindowsImpersonationContext of the new users identity.            ///             /// Username you want to impersonate            /// Logon domain            /// User's password to logon with            ///             public Impersonator(string sUsername, string sDomain, string sPassword)            {                // initialize tokens                IntPtr pExistingTokenHandle = new IntPtr(0);                IntPtr pDuplicateTokenHandle = new IntPtr(0);                pExistingTokenHandle = IntPtr.Zero;                pDuplicateTokenHandle = IntPtr.Zero;                // if domain name was blank, assume local machine                if (sDomain == "")                    sDomain = System.Environment.MachineName;                try                {                    const int LOGON32_PROVIDER_DEFAULT = 0;                    // create token                    // const int LOGON32_LOGON_INTERACTIVE = 2;                    const int LOGON32_LOGON_NEW_CREDENTIALS = 9;                    //const int SecurityImpersonation = 2;                    // get handle to token                    bool bImpersonated = LogonUser(sUsername, sDomain, sPassword,                        LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);                    // did impersonation fail?                    if (false == bImpersonated)                    {                        int nErrorCode = Marshal.GetLastWin32Error();                        // show the reason why LogonUser failed                        throw new ApplicationException("LogonUser() failed with error code: " + nErrorCode);                    }                    bool bRetVal = DuplicateToken(pExistingTokenHandle, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, ref pDuplicateTokenHandle);                    // did DuplicateToken fail?                    if (false == bRetVal)                    {                        int nErrorCode = Marshal.GetLastWin32Error();                        CloseHandle(pExistingTokenHandle); // close existing handle                        // show the reason why DuplicateToken failed                        throw new ApplicationException("DuplicateToken() failed with error code: " + nErrorCode);                    }                    else                    {                        // create new identity using new primary token                        WindowsIdentity newId = new WindowsIdentity(pDuplicateTokenHandle);                        WindowsImpersonationContext impersonatedUser = newId.Impersonate();                        newUser = impersonatedUser;                    }                }                finally                {                    // close handle(s)                    if (pExistingTokenHandle != IntPtr.Zero)                        CloseHandle(pExistingTokenHandle);                    if (pDuplicateTokenHandle != IntPtr.Zero)                        CloseHandle(pDuplicateTokenHandle);                }            }            public void Undo()            {                newUser.Undo();            }        }    }

To use it just:

Impersonator impersonator = new Impersonator("username", "domain", "password");

//Connect to and use SQL server

impersonator.Undo();

我添加了 Undo 方法,否则模拟对象往往会被垃圾回收。我还更改了代码以使用 LOGON32_LOGON_NEW_CREDENTIALS 但这是一个戳一下并运行以使其工作;我仍然需要完全理解它的作用,我感觉它与 runas 上的/netonly 标志相同。我还将稍微分解一下构造函数。

关于c# - 从非域计算机连接到域 SQL Server 2005,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2822449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com