Мне не удается подключиться к SQL Server с сервера приложений, когда серверы SQL и App существуют в разных доменах, даже после использования олицетворения.
Наше приложение (служба Windows) работает как существующая учетная запись "acc1"в домене "MyDomain1" и должен подключиться к серверу SQL, который существует в домене "MyDomain2".Поскольку «acc1» не имеет доступа к SQL Server, мы олицетворяем «acc2» для подключения с использованием аутентификации Windows.Это прекрасно работает, когда серверы приложений и SQL находятся в одном домене.
Но когда серверы приложений и SQL существуют в разных доменах, мы получаем следующую ошибку: «Ошибка входа в систему. Вход в систему из ненадежного домена и его нельзя использовать для проверки подлинности Windows».
В SQL Server невозможно включить аутентификацию в смешанном режиме из-за ограничений безопасности.Можно использовать только проверку подлинности Windows.
Может ли кто-нибудь помочь с этим?
safeTokenHandle = ImpersonationHelper.GetSafeTokenHandle("MyDomain2","acc2","Password2");
newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
impersonatedUser = newId.Impersonate();
И класс ImpersonationHelper, как показано ниже
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
namespace Impersonation.Helpers
{
public class ImpersonationHelper
{
public static object MessageBox { get; private set; }
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public static SafeTokenHandle GetSafeTokenHandle(string domainName, string userName, string password)
{
SafeTokenHandle safeTokenHandle;
try
{
bool returnValue = LogonUser(userName, domainName, password,
(int)LogonType.NewCredentials, (int)LogonProvider.WinNT50,
out safeTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine(string.Format("LogonUser failed with error code : {0}", ret));
throw new System.ComponentModel.Win32Exception(ret);
}
return safeTokenHandle;
}
catch (Exception ex)
{
throw ex;
}
}
}
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);
}
}
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
}
}