security - 如何验证域凭据(来自 native 代码)?

标签 security kerberos ntlm networkcredentials

我想针对域 Controller 验证一组凭据。例如:

Username: joel
Password: splotchy
Domain:   STACKOVERFLOW

在 .NET 3.5 及更高版本中 you can use PrincipalContext.ValidateCredentials(username, password) .

否则你就有麻烦了。

遵循 Microsoft 知识库文章 How to validate user credentials on Microsoft operating systems 中的代码,我到了你打电话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)

The function failed. No authority could be contacted for authentication. This could be due to the following conditions:

  • The domain name of the authenticating party is incorrect.
  • The domain is unavailable.
  • The trust relationship has failed.

这将是一个有用的错误,除了我可以使用以下方法验证 .NET 3.5 中的相同凭据:

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

可能会发生什么情况,允许 .NET 验证一组凭据,而 native 代码却不能?

<小时/>

更新:LogonUser也失败:

LogonUser("joel@stackoverflow.com", null, "splotchy", 
      LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_WINNT50, out token);

1311 - There are currently no logon servers available to service the logon request
<小时/>

更新二:我尝试了首选的 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

最佳答案

我认为这是为了解决与另一个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. 对本地用户进行身份验证

您可以通过与域 Controller 进行正确的 SSPI 握手来实现前两种情况。您在另一个问题中提到的知识库文章正在执行环回 SSPI 握手。在第一种情况下它不起作用,因为客户端计算机不信任您正在验证的域。这应该就是您看到 SEC_E_NO_AUTHENTICATING_AUTHORITY 的原因。

简而言之,如果您想做与

完全相同的事情
PrincipalContext.ValidateCredentials(username, password);

您需要以不同于域用户的方式处理本地用户。对于域用户,您需要调用ldap_bind_s使用给定的凭据绑定(bind)到域 Controller 。对于本地用户,您需要使用ADsOpenObject使用给定的凭据绑定(bind)到 WinnT://YourComputerName。这就是我在 Reflector 中读到的 PrincipalContext.ValidateCredentials 所做的事情。

我认为没有任何等效的单一原生 API 可以为您做同样的事情。

关于security - 如何验证域凭据(来自 native 代码)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9723844/

相关文章:

security - 如何在 postgresql 中散列密码?

security - 使用 SecAsn1Decode 解析 DER 格式数据

security - 基于 token 的安全策略和注意事项

tomcat kerberos认证+ldap授权

java - Java 升级后,NTLM 不再与 Java WebStart 一起使用

javascript - 如何保护使用 javax.scripting 运行的脚本?

Java 代理身份验证(使用 HttpURLConnection)

python - 将 Kerberos 身份验证与 Paramiko 结合使用

java - Apache CXF 3.1.6 Web 服务客户端 - NTLM 身份验证

internet-explorer - Symfony 2 上的 NTLM 身份验证