如何针对Active Directory验证用户名和密码?我只是想检查用户名和密码是否正确.
有人问过,并回答过.NET,但是现在是时候得到原生Win32代码的答案了:
如何验证Windows用户名和密码?
我之前问过托管代码这个问题.现在是原生解决方案的时候了.
需要指出一些更常见的解决方案的陷阱:
很多人建议查询Active Directory.如果抛出异常,那么您知道凭据无效 - 正如此stackoverflow问题中所建议的那样.
您不仅要对域帐户进行身份验证,还要进行隐式授权检查.也就是说,您正在使用模拟令牌从AD中读取属性.如果其他有效帐户无权从AD读取,该怎么办?默认情况下,所有用户都具有读取权限,但可以将域策略设置为禁用受限帐户(和/或组)的访问权限.
绑定AD会产生严重的开销,必须在客户端加载AD架构缓存(DirectoryServices使用的ADSI提供程序中的ADSI缓存).这既是网络又是AD服务器,消耗资源 - 而且对于像验证用户帐户这样的简单操作来说太昂贵了.
您依赖于非例外情况的异常失败,并假设这意味着无效的用户名和密码.然后,其他问题(例如,网络故障,AD连接故障,内存分配错误等)被错误地表示为身份验证失败.
使用DirectoryEntry该类是.NET是验证凭据的错误方法的示例:
无效的方法1a - .NET
DirectoryEntry entry = new DirectoryEntry("persuis", "iboyd", "Tr0ub4dor&3");
object nativeObject = entry.NativeObject;
Run Code Online (Sandbox Code Playgroud)
无效的方法1b - .NET#2
public static Boolean CheckADUserCredentials(String accountName, String password, String domain)
{
Boolean result;
using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, accountName, password))
{
using (DirectorySearcher searcher = new DirectorySearcher(entry))
{ …Run Code Online (Sandbox Code Playgroud) 我想针对域控制器验证一组凭据.例如:
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", …Run Code Online (Sandbox Code Playgroud) 我正在尝试根据提供的用户名和密码对本地用户进行身份验证。我遇到了这个线程:针对 Active Directory 验证用户名和密码?
这是我验证用户的方式:
PrincipalContext pc = new PrincipalContext(ContextType.Machine);
bool isValid = pc.ValidateCredentials(user, pass);
Run Code Online (Sandbox Code Playgroud)
只要我在网络上它就可以工作,但是如果我断开计算机的连接,它会给我:
找不到网络路径。
我要做的就是在本地机器上进行验证,该机器可能是网络的一部分,也可能不是网络的一部分。
编辑:UserPrincipal.FindByIdentity 似乎在没有 AD 的情况下仍然有效,是 pc.ValidateCredentials 给我带来了麻烦。
我需要一些C#代码来验证Windows凭证,该帐户可能是本地帐户或域帐户.
请提供一些有关如何操作的建议.