Ian*_*oyd 7 security ntlm kerberos networkcredentials
我想针对域控制器验证一组凭据.例如:
Username: joel
Password: splotchy
Domain: STACKOVERFLOW
Run Code Online (Sandbox Code Playgroud)
在.NET 3.5及更高版本中,您可以使用PrincipalContext.ValidateCredentials(username, password).
否则你就麻烦了.
按照Microsoft知识库文章如何验证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
Run Code Online (Sandbox Code Playgroud)
除了函数失败:
SEC_E_NO_AUTHENTICATING_AUTHORITY(0x80090311)功能失败了.无法联系任何权限进行身份验证.这可能是由于以下条件:
- 身份验证方的域名不正确.
- 该域名不可用.
- 信任关系失败了.
这将是一个有用的错误,除了我可以使用以下方法从.NET 3.5验证相同的凭据:
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain))
{
valid = context.ValidateCredentials(username, password);
}
Run Code Online (Sandbox Code Playgroud)
可能发生什么允许.NET验证一组凭据,而本机代码不能?
更新:LogonUser也失败了:
LogonUser("joel@stackoverflow.com", null, "splotchy",
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_WINNT50, out token);
Run Code Online (Sandbox Code Playgroud)
同
1311 - There are currently no logon servers available to service the logon request
Run Code Online (Sandbox Code Playgroud)
更新二:我已尝试过首选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
Run Code Online (Sandbox Code Playgroud)
我认为这是为了解决与您发布的另一个问题相同的问题。
我有点明白你现在想做什么。让我回顾一下您在另一篇文章中写的内容。
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
Run Code Online (Sandbox Code Playgroud)
你想要
您可以通过与域控制器进行正确的 SSPI 握手来实现前两种情况。您在另一个问题中提到的知识库文章正在执行环回 SSPI 握手。在第一种情况下它不起作用,因为客户端计算机不信任您正在验证的域。这应该就是你看到的原因SEC_E_NO_AUTHENTICATING_AUTHORITY。
简而言之,如果您想做与
PrincipalContext.ValidateCredentials(username, password);
Run Code Online (Sandbox Code Playgroud)
您需要以不同于域用户的方式处理本地用户。对于域用户,您需要调用ldap_bind_s使用给定的凭据绑定到域控制器。对于本地用户,您需要使用ADsOpenObject使用给定的凭据绑定到WinnT://YourComputerName 。这就是PrincipalContext.ValidateCredentials我在 Reflector 中读到的内容。
我不认为有任何等效的单一原生 API 可以为您做同样的事情。