2012-03-15 6 views
6

Я хочу проверить набор учетных данных против контроллера домена. например:Как проверить учетные данные домена (из собственного кода)?

Username: joel 
Password: splotchy 
Domain: STACKOVERFLOW 

В .NET 3.5 и новее you can use PrincipalContext.ValidateCredentials(username, password).

В противном случае у вас проблемы.

После кода в статье How to validate user credentials on Microsoft operating systems базы знаний Microsoft, я добраться до точки, где вы называете 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 

за исключением того, что функция терпит неудачу с:

SEC_E_NO_AUTHENTICATING_AUTHORITY (0x80090311)

Функция не удалась. К аутентификации не разрешено обращаться ни с кем. Это может быть связано со следующими условиями:

  • Доменное имя аутентифицирующей стороны неверно.
  • Домен недоступна.
  • Отношения доверия не удались.

Это было бы полезно ошибки, за исключением того, что я могу подтвердить те же учетные данные с .NET 3.5 с помощью:

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

Что могло случиться, что позволяет .NET проверить набор учетных данных , в то время как собственный код не может?


Update: LogonUser также не:

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

с

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

Update Два: Я пытался как предпочтительный Negotiate поставщика, а также как е Windows NT4 наследие «NTLM» поставщик

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

Как вы называете 'InitializeSecurityContext'? (Какой SSP, в частности?) Как вы настраиваете «CredHandle»? –

+0

@EdwardThomson Я пробовал предпочтительный поставщик 'Negotiate', а также' NTLM'. «CredHandle» инициализируется вызовом 'AcquireCredentialsHandle'. –

+0

Кажется, я помню, что у меня была аналогичная проблема, хотя это было много лет назад, и проблема нечеткая. Есть ли какие-либо изменения, если вы выполняете w/повышенные разрешения? (Возможно, администратор домена?) –

ответ

0

Я полагаю, что это решить ту же проблему другой question что вы публикуемую.

Я понимаю, что вы сейчас пытаетесь сделать. Позвольте мне вспомнить, что вы написали на другом посту.

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 

Вы хотите

  1. аутентифицировать пользователь из домена, что ваша машина не доверяет
  2. аутентифицировать пользователь из домена, что ваша машина доверенного
  3. Аутентифицировать локальный пользователь

Вы можете добиться первых двух случаев, выполнив правильное установление связи SSPI с контроллером домена , Статья в KB, о которой вы говорите в другом вопросе, делает обратную связь SSPI с обратной связью. Он не будет работать в случае номер один, потому что клиентская машина не доверяет домену, к которому вы аутентифицируетесь. Вот почему вы видите SEC_E_NO_AUTHENTICATING_AUTHORITY.

Чтобы вырезать Короче говоря, если вы хотите, чтобы делать то же самое, как

PrincipalContext.ValidateCredentials(username, password); 

вам нужно обрабатывать локального пользователя по-разному от пользователя домена. Для пользователя домена вам необходимо позвонить ldap_bind_s для привязки к контроллеру домена с использованием данных учетных данных. Для локального пользователя вам необходимо использовать ADsOpenObject для привязки к WinnT: // YourComputerName с использованием заданных учетных данных. Это то, что PrincipalContext.ValidateCredentials делает из того, что я читаю в рефлекторе.

Я не вижу, чтобы какой-либо эквивалентный один собственный API-интерфейс выполнял то же самое для вас.