背景,需要在当前上下文中连接两个数据库,且两个数据库都需要使用不同的域账号登录。
首先注意到SqlConnection 对象有个重载的方法,但看了描述貌似不支持 Windows 集成身份验证。
经测试,确实不支持
那么尝试另外的方法,尝试用C#代码使用另外的用户登录,然后使用新用户的上下文执行一些操作,完整代码如下,需要使用管理员账号执行。当然,该操作不仅限于连接数据库
using Microsoft.Win32.SafeHandles; using System; using System.Data.SqlClient; using System.Runtime.InteropServices; using System.Security.Principal; namespace ConsoleApp2 { class Program { [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeAccessTokenHandle phToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); static void Main(string[] args) { //var conn = new SqlConnection(); var userName = "xxxx"; var password = "xxxxx"; var domainName = "xxxxx"; const int LOGON32_PROVIDER_DEFAULT = 0; //This parameter causes LogonUser to create a primary token. const int LOGON32_LOGON_INTERACTIVE = 2; SafeAccessTokenHandle safeAccessTokenHandle; bool returnValue = LogonUser(userName, domainName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeAccessTokenHandle); Console.WriteLine("模拟前:"); Console.WriteLine("Current User:" + WindowsIdentity.GetCurrent().Name); WindowsIdentity.RunImpersonated(safeAccessTokenHandle, () => { Console.WriteLine("模拟中:"); Console.WriteLine("Current User:" + WindowsIdentity.GetCurrent().Name); try { var conn = new SqlConnection("Server=remoteserver1;Database=DbName;Trusted_Connection=SSPI;" ); conn.Open(); var cmd = new SqlCommand("select 1", conn); Console.WriteLine(cmd.ExecuteScalar()); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }); Console.WriteLine("模拟后:"); Console.WriteLine("Current User:" + WindowsIdentity.GetCurrent().Name); } } }