我问一个问题前几天(接到SQL服务器2005年从非域机使用Windows身份验证)它得到了一些有趣的,但不可用的建议。我想要问的问题,但是明确什么我的约束:

我有一个窗域内哪一个机器运行SQL服务器2005年及其配置,以支持只有窗户身份验证。我要运行一个C#客户应用程序的机关的同一个网络,但这是不对的领域,并访问数据库SQL服务器上2005年实例。

我无法创建或修改操作系统或SQL服务器的用户在任一机,并且我无法做任何改动的权限或模拟,我不能使用的运行方式.

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

C#我已经尝试了各种周围的事物:

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

并试图设置的综合安全真假,但似乎没有任何工作。为什么我试图做根本不可能在C#?

谢谢你任何帮助,马丁

有帮助吗?

解决方案

当你正确地说,JDBC或Perl在Linux机器上既可以连接到SQL服务器的使用Windows身份验证并凭证从当前登录的用户是不同的。 同样是真实的Windows CE设备,顺便说一句。

我认为这是,这是不是C#,但在SQL Server OLE DB驱动程序的问题。我想上面提到的方法“假装用一些具体的凭据是Windows机器”在网络上水平;一个功能,它的SQL Server的OLE DB驱动程序缺乏。因此,我的建议是寻找替代(也许商业的?)OLE DB驱动程序可以访问SQL Server数据库。我不知道,如果这样的事情存在,但。

其他提示

我有一个类似的问题,我正在写一个工具,需要在一个域和验证与其他域上的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命令使其很难调试应用程序,并没有闻到好。

最后,我发现这篇文章在代码项目这是谈论认证操纵活动目录,这里是做冒充主类:

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

要使用它只是:

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

//Connect to and use SQL server

impersonator.Undo();

我在撤消方法添加否则假冒者对象趋向于得到垃圾收集。我也改变了代码使用LOGON32_LOGON_NEW_CREDENTIALS但这是一个戳和运行,使工作;我还需要充分理解它做什么,我有一种感觉它一样运行方式上与/ netonly标志。我还打算打破构造一个位。

是没用的指定用户名和密码连串因为那些暗示SQL身份验证,你已经指定SQL服务器只接受窗户身份验证。

如果服务器不允许SQL认证后 可以连接被以使用Windows身份验证,即。 IntegratedSecurity=true.这意味着你的客户会认证为什么凭证的运行过程中(或正在目前模拟的).

为了窗户身份验证工作,你必须选择下列之一:

  • 加入非域参加机进入一个域名(它可以它自己的领域!) 该信托基金的服务领域,然后运行的客户进程作为一个域\用户证书。
  • 使用NTLM镜像账户:一对的上的本地用户的客户和服务器用相同的名称和密码。
  • 授予作为匿名接到SQL服务器。

如果你无法使客户主的信任的服务器域,也没有可以添加NTLM镜像帐户和SQL服务器的管理是理智不足以使匿名的,那么你就不能连接。

您必须配置SQL Server ,以允许SQL Server身份验证即认证用的用户名和密码。

可以不是由“喜欢”服务器认证域的用户名/口令认证,即直接指定域的用户名/密码。

我可能是错的,当然,但我敢肯定,这不是C#或.NET的一个问题。你怎么能在你的Perl或Java应用程序?

SQL Server上的登录

我给你在Java答案,我更熟悉的:我用上面提到的四个参数JTDS JDBC驱动程序。 Perl的应用程序,我知道少谈,但在Linux机器上运行,并且能够使用相同的参数进行连接。我不能更改SQL Server以支持SQL身份验证。

要回答Remus的建议,我不能做任何的这三样东西,他建议,但Java和Perl应用程序能够连接。任何其他的想法?

谢谢,马丁

它是一个选项,以提示凭据的?

下面是示例代码,我使用使用JTDS JDBC驱动从非域机器连接:

的Class.forName( “net.sourceforge.jtds.jdbc.Driver”)的newInstance(); 字符串URL = “JDBC:JTDS:SQLSERVER://服务器/数据库;域=域”; 康恩=的DriverManager.getConnection(URL, “用户”, “密码”);

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top