2012-03-15 12 views
6

quiero validar un conjunto de credenciales contra el controlador de dominio. ej .:¿Cómo validar las credenciales de dominio (del código nativo)?

Username: joel 
Password: splotchy 
Domain: STACKOVERFLOW 

En .NET 3.5 y versiones posteriores you can use PrincipalContext.ValidateCredentials(username, password).

De lo contrario, estás en problemas.

Siguiendo el código en el artículo How to validate user credentials on Microsoft operating systems Microsoft Knowledge Base, llego al punto en el que se llama a AcceptSecurityContext:

ss = AcceptSecurityContext(
     @pAS._hcred,   //[in]CredHandle structure 
     phContext,    //[in,out]CtxtHandle structure 
     @InBuffDesc,   //[in]SecBufferDesc structure 
     0,      //[in]context requirement flags 
     SECURITY_NATIVE_DREP, //[in]target data representation 
     @pAS._hctxt,   //[in,out]CtxtHandle strcture 
     @OutBuffDesc,   //[in,out]SecBufferDesc structure 
     ContextAttributes,  //[out]Context attribute flags 
     @Lifetime);   //[out]Timestamp struture 

excepto que la función falla con:

SEC_E_NO_AUTHENTICATING_AUTHORITY (0x80090311)

La función ha fallado. No se pudo contactar a ninguna autoridad para la autenticación. Esto podría deberse a las siguientes condiciones:

  • El nombre de dominio de la parte que realiza la autenticación es incorrecto.
  • El dominio no está disponible.
  • La relación de confianza ha fallado.

Esto sería un error útil, excepto que yo pueda validar las mismas credenciales de .NET 3.5 usando:

using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain)) 
{ 
    valid = context.ValidateCredentials(username, password);     
} 

Qué podría estar sucediendo que permite .NET para validar un conjunto de credenciales , mientras que el código nativo no puede?


actualización: LogonUser también falla:

LogonUser("[email protected]", null, "splotchy", 
     LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_WINNT50, out token); 

con

1311 - There are currently no logon servers available to service the logon request 

actualizar dos: He intentado tanto el Negotiate de proveedores preferidos, así como TH correo de Windows NT4 legado "NTLM" proveedor de

String package = "Negotiate"; //"NTLM" 

QuerySecurityPackageInfo(package, [out] packageInfo); 
... 
AcquireCredentialsHandle(
     null,     //[in] principle 
     package,    //[in] package 
     SECPKG_CRED_OUTBOUND, //[in] credential use 
     null,     //[in] LogonID 
     pAuthIdentity,  //[in] authData 
     null,     //[in] GetKeyFn, not used and should be null 
     null,     //[in] GetKeyArgument, not used and should be null 
     credHandle,   //[out] CredHandle structure 
     expires);    //[out] expiration TimeStamp structure 
+0

¿Cómo se llama 'InitializeSecurityContext'? (¿Qué SSP, en particular?) ¿Cómo está configurando el 'CredHandle'? –

+0

@EdwardThomson He intentado el proveedor 'Negociar' preferido, así como' NTLM'. El 'CredHandle' se inicializa mediante una llamada a' AcquireCredentialsHandle'. –

+0

Parece que recuerdo haber tenido un problema similar, aunque esto fue hace años y el problema es confuso. ¿Hay algún cambio si ejecuta w/permisos elevados? (Dominio de administrador tal vez?) –

Respuesta

0

supongo que se trata de resolver el mismo problema que el otro question que usted envió.

Entiendo lo que intenta hacer ahora. Déjame resumir lo que escribiste en otra publicación.

Username Password Domain    Machine on domain? Validate as 
======== ======== ================= ================== ============== 
iboyd  pass1  .     No     Local account 
iboyd  pass1  (empty)   No     Local account 
iboyd  pass1  stackoverflow.com No     Domain account 
iboyd  pass1  .     Yes     Local account 
iboyd  pass1  (empty)   Yes     Domain account 
iboyd  pass1  stackoverflow.com Yes     Domain account 

Usted quiere

  1. autenticar a un usuario de un dominio que su máquina no confía
  2. autenticar a un usuario de un dominio que su máquina de confianza
  3. autenticar a un usuario local

Puede lograr los dos primeros casos al hacer un correcto apretón de manos SSPI con el controlador de dominio . El artículo de KB al que te refieres en otra pregunta es hacer un bucle de saludo SSPI. No va a funcionar en el caso número uno porque la máquina cliente no confía en el dominio en el que se está autenticando. Esa debería ser la razón por la que está viendo SEC_E_NO_AUTHENTICATING_AUTHORITY.

En resumidas cuentas, si quieres hacer exactamente lo mismo que

PrincipalContext.ValidateCredentials(username, password); 

que necesita para manejar el usuario local diferente a la de usuario de dominio. Para el usuario de dominio, debe llamar al ldap_bind_s para vincularse al controlador de dominio con las credenciales especificadas. Para el usuario local, debe usar ADsOpenObject para enlazar al WinnT: // YourComputerName usando las credenciales proporcionadas. Esto es lo que PrincipalContext.ValidateCredentials está haciendo a partir de lo que leo en el Reflector.

No veo que haya una sola API nativa equivalente que haga lo mismo por usted.

Cuestiones relacionadas