sql server - usuario - Autenticar contra un dominio no confiable de la aplicación WPF
para que sirve el usuario sa en sql server (3)
Bueno, parece que tal vez se puede hacer después de todo. Encontré el siguiente enlace , y eso me llevó a darme cuenta de que mi problema principal era el uso incorrecto del parámetro LOGON32_LOGON_INTERACTIVE para la llamada de la API LogonUser (debería haber sido LOGON32_LOGON_NEWCREDENTIALS).
Como tal, ahora puedo usar el siguiente código para conectarme a una base de datos en SQL Server, protegida por Autenticación de Windows pero en un dominio totalmente no relacionado con la estación de trabajo desde la cual se ejecuta el código ...
static void Main (cadena [] args) {
SafeTokenHandle safeTokenHandle;
try {
string userName = @"*****", domainName = @"*****", password = @"*****";
bool returnValue = NativeMethods.LogonUser(userName, domainName, password,
NativeMethods.LogonType.NewCredentials, NativeMethods.LogonProvider.Default, out safeTokenHandle);
if (false == returnValue) {
int ret = Marshal.GetLastWin32Error();
Console.WriteLine("LogonUser failed with error code : {0}", ret);
throw new Win32Exception(ret);
}
using (safeTokenHandle) {
WindowsIdentity windowsIdentity = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
using (WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate()) {
using (DataTable table = new DataTable()) {
using (SqlDataAdapter adapter = new SqlDataAdapter()) {
using (adapter.SelectCommand = new SqlCommand(@"select * from dbo.MyTable")) {
adapter.SelectCommand.CommandType = CommandType.Text;
using (adapter.SelectCommand.Connection = new SqlConnection(@"Data Source=Server;Initial Catalog=Database;Integrated Security=Yes")) {
adapter.SelectCommand.Connection.Open();
adapter.Fill(table);
}
}
}
Console.WriteLine(string.Format(@"{0} Rows retrieved.", table.Rows.Count));
}
}
}
}
catch (Exception ex) {
Console.WriteLine("Exception occurred. " + ex.Message);
}
Por supuesto, es necesario ponerlo en orden y necesito pedirle al usuario sus credenciales (no hay forma de que me convenzan de las credenciales del código) pero, en principio, funciona (salvo la anonimización).
Espero que esto ayude a otra persona en algún momento.
Ah, y también necesitarás lo siguiente ...
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid {
private SafeTokenHandle() : base(true) {
}
protected override bool ReleaseHandle() {
return NativeMethods.CloseHandle(handle);
}
}
[DllImport(@"kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(
IntPtr handle);
[DllImport(@"advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(
String lpszUsername,
String lpszDomain,
String lpszPassword,
LogonType dwLogonType,
LogonProvider dwLogonProvider,
out SafeTokenHandle phToken);
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
}
Tengo una aplicación WPF que requiere acceso a una base de datos de SQL Server 2008 R2. La base de datos está protegida usando el directorio activo. La aplicación funciona bien en estaciones de trabajo que están conectadas al dominio y donde el usuario ha iniciado sesión exitosamente.
Ahora necesito poder ejecutar la misma aplicación en estaciones de trabajo conectadas a un dominio diferente. Desafortunadamente, este nuevo dominio está controlado por SBS y, como tal, no puedo establecer una relación de confianza entre ellos.
Efectivamente, lo que (creo que) necesito es una facilidad para permitir que un usuario ingrese las credenciales que se han configurado en el dominio que aloja el servidor de base de datos (nombre de usuario y contraseña) y luego suplantar a ese usuario al conectarse al servidor de la base de datos.
Probé la muestra de Microsoft usando LogonUser, LOGON32_PROVIDER_DEFAULT & LOGON32_LOGON_INTERACTIVE pero parece que no hago lo que quiero, en cambio me quejo de que no puedo iniciar sesión porque la estación de trabajo que estoy usando no tiene una cuenta de dominio.
¿Alguien tiene alguna sugerencia alternativa?
Tengo una sugerencia ... pero no creo que te vaya a gustar.
Use SQL Autenticación en lugar de Integrado.
Tuve un problema similar y, después de trabajarlo, resultó que realmente no había un método para hacerlo realidad. Vea aquí mi publicación en dba.stackexchange.com
Si el uso de Autenticación SQL no es una opción, todavía "puede" haber una forma de cinta adhesiva / cableado / piratería total para hacerlo, pero probablemente tendrías que migrar la pregunta a uno de los foros del administrador del servidor y no a . - ya que ya no es una pregunta de programación.
CON SU CONFIGURACIÓN ACTUAL
The database is secured using active directory
Supongo que quiere decir que su conexión SQL usa la autenticación de Windows. De cualquier manera, hay un poco más de lo que tal vez te das cuenta. Si está utilizando el "directorio activo" para las identidades de autenticación, apostaría a que confía en la autenticación Kerberos para Windows (no es solo su tipo de autenticación, sino también su tipo de credencial). El artículo que he vinculado explica la diferencia entre Kerberos y NTLM para SQL Server 2005, pero es el mismo para 2008 R2.
Desafortunadamente, sin la relación de confianza entre los dominios, no importa si se hace pasar por un usuario en el dominio que aloja la base de datos, no podrá conectarse (como lo atestigua). Necesitas esa relación de confianza .
Si logra establecer una relación de confianza entre los dominios, he publicado cómo lograr la autenticación de Windows entre dominios para SQL Server usando grupos de dominio aquí , que pueden serle útiles.
CONFIGURACIÓN ALTERNATIVA
Si no desea utilizar la autenticación de SQL (no me gustan las credenciales de empaquetado con mis aplicaciones), lo animo a que separe las operaciones de su base de datos en una arquitectura más orientada al servicio. Por lo tanto, el trabajo de SQL real que se realiza iría a un servicio WCF (que está alojado en el mismo dominio que su base de datos y se hace pasar por la identidad del servicio) y su aplicación simplemente solicitará el servicio. Luego puede usar NTLM para proteger su servicio web y seguir usando la autenticación de Windows. De esta manera, aún puede verificar quién es el usuario solicitante y confiar en sus propias estructuras de seguridad básicas (es decir, tablas simples) para autorizar el uso.
Avíseme si esto no tiene sentido para usted o si necesita más aclaraciones.