我想要验证一组凭据对网域控制器。例如:
Username: STACKOVERFLOW\joel
Password: splotchy
很多人建议在 ActiveDirectory 中查询一些东西。如果抛出异常,那么您就知道凭据是无效的——正如 这个堆栈溢出的问题中所建议的那样。
然而,还有一些重要的 这种方法的缺点:
您不仅要对域帐户进行身份验证,还要执行隐式授权检查。也就是说,您正在使用模拟标记从 AD 读取属性。如果原本有效的帐户没有读取广告的权限怎么办?默认情况下,所有用户都具有读访问权限,但是可以设置域策略来禁用受限帐户(和组)的访问权限。
针对 AD 的绑定有严重的开销,必须在客户端加载 AD 模式缓存(DirectoryServices 使用的 ADSI 提供程序中的 ADSI 缓存)。这既是网络,也是广告服务器,资源消耗-和太昂贵的一个简单的操作,如认证用户帐户。
对于非异常情况,您依赖于异常故障,并假设这意味着无效的用户名和密码。其他问题(如网络故障、 AD 连接故障、内存分配错误等)则被误解为身份验证失败。
其他人则建议使用 LogonUser()
API 函数。这听起来不错,但不幸的是,调用用户有时需要一个通常只给予操作系统本身的权限:
调用 LogonUser 的进程需要 SE _ TCB _ NAME 特权 调用进程没有这个 权限,LogonUser 失败,并且 返回 GetLastError ERROR _ PRIVILEGE _ NOT _ HELD.
在某些方面 例,调用 LogonUser 还必须具有 SE _ Change _ NOTIFY _ NAME 特权 启用; 否则,LogonUser 将失败 和 GetLastError 返回 错误 _ ACCESS _ DENIED。此特权是 本地系统不需要 会员帐户 管理员组的 默认情况下,SE _ ChangGE _ NOTIFY _ NAME 为 为所有用户启用,但一些 管理员可能会禁用它 所有人。
授予“ 作为操作系统的一部分”特权不是你想随意做的事情,正如微软在 知识库文章知识库文章中指出的那样:
这个过程正在召唤 LogonUser 必须具有 SE _ TCB _ NAME 特权(在用户管理器中,这是 作为操作的一部分 System ”right) . SE _ TCB _ NAME 特权是非常强大的 不应授予任何任意用户,以便他们可以 运行一个应用程序 ,该应用程序需要 验证证书。
此外,如果指定了空白密码,则对 LogonUser()
的调用将失败。
对一组域凭据进行身份验证的正确方法是什么?
我 发生了是从托管代码调用,但这是一个一般的 Windows 问题。可以假定客户具有。安装了 NET Framework 2.0。