故障排除帮助:Active Directory 绑定失败
我正在尝试诊断在客户端站点上运行的服务器应用程序的问题。所述应用程序根据 AD 环境中的域控制器对用户凭据进行身份验证。我们看到的行为是定期没有用户可以通过服务器进行身份验证。
我们基本上将失败追溯到“绑定”失败。为了进一步诊断问题,我构建了一个超级简单的工具,它执行两种类型的绑定:一种使用 LDAP 服务器绑定,一种使用 WinNT 绑定。我们的服务器应用程序仅进行 LDAP 绑定,但为了添加控件,我引入了 WinNT 绑定。
public static void DoWinNTBind(string domain, string login, string password)
{
Logger.Log("Starting WinNT Bind to {0}",domain);
try
{
var serverPath = String.Format("WinNT://{0}",domain);
Logger.Log("Creating DirectoryEntry object for {0} on domain {1}", login, serverPath);
using (DirectoryEntry de = new DirectoryEntry(serverPath, login, password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing))
{
if (!de.NativeObject.Equals(null))
{
Logger.Log("WinNT Bind Success");
}
else
{
Logger.Log("WinNT Bind Failed");
}
}
}
catch(Exception ex)
{
Logger.Log("{0} occured during WinNT Bind: {1}",ex.GetType().Name,ex.Message);
Logger.Log("Stack: {0}",ex.StackTrace);
}
}
public static void DoLDAPBind(string domain,string login, string password)
{
Logger.Log("Starting LDAP Bind to {0}",domain);
try
{
var serverPath = String.Format("LDAP://{0}",domain);
Logger.Log("Creating DirectoryEntry object for {0} on domain {1}", login, serverPath);
using (DirectoryEntry de = new DirectoryEntry(serverPath, login, password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing))
{
if (!de.NativeObject.Equals(null))
{
Logger.Log("LDAP Bind Success");
}
else
{
Logger.Log("LDAP Bind Failed");
}
}
}
catch(Exception ex)
{
Logger.Log("{0} occured during LDAP Bind: {1}",ex.GetType().Name,ex.Message);
Logger.Log("Stack: {0}",ex.StackTrace);
}
}
正如您所看到的,除了使用 System.DirectoryServices.DirectoryEntry 连接到 DC 之外,没有太多代码。
生成的日志文件是(名称和域屏蔽)。
6/29/2010 2:52:17 PM:执行 AD 绑定用户 1 6/29/2010 2:52:17 PM: 启动 LDAP 绑定到 xxx.xxx 6/29/2010 2:52:17 PM:创建 域的 DirectoryEntry 对象 LDAP://xxx.xxx 6/29/2010 2:52:17 下午: 发生 DirectoryServicesCOMException LDAP 绑定期间:登录失败: 未知的用户名或错误的密码。
6/29/2010 2:52:17 PM:堆栈:位于 System.DirectoryServices.DirectoryEntry.Bind(布尔值 如果失败则抛出) System.DirectoryServices.DirectoryEntry.Bind() 在 System.DirectoryServices.DirectoryEntry.get_NativeObject() 在 AdmitOne.Superglue.ActiveDirectoryHelper.DoLDAPBind(字符串 域、字符串登录名、字符串密码) 在 C:\Projects\Galapagos\branches\Contract\2.0_SN_Peer\Src\Tools\Superglue\ActiveDirectoryHelper.cs:line 47 2010 年 6 月 29 日下午 2:52:17:开始 WinNT 绑定到 xxx.xxx 2010 年 6 月 29 日 2:52:17 PM:创建 DirectoryEntry 域中 user1 的对象 WinNT://xxx.xxx 6/29/2010 2:52:18 下午: WinNT绑定成功
因此,相同的用户名使用 LDAP 绑定失败,但使用 WinNT 绑定成功!
在我们的本地测试环境中,我们没有看到这种行为,LDAP 和 WinNT 都成功,没有任何问题。
所以我被困住了。我想说这是他们AD环境的问题,但没有确凿证据,我不能。
我首先询问堆栈,以确保我的绑定代码是正确的。之后,我可能需要重新询问 Serverfault,这是询问 AD 特定问题的更合适的地方。
I'm trying to diagnose a problem with a server application running on a Client site. Said application authenticates user credentials against a Domain Controller in an AD environment. The behavior we're seeing is periodically no users can authenticate through the server.
We've essentially traced the failure to the "bind" failing. To further diagnose the issue, I built a super simple tool that does two types of binds: one using an LDAP server bind, and one use WinNT bind. Our server application only does LDAP bind, but to add a control, I threw in the WinNT bind.
public static void DoWinNTBind(string domain, string login, string password)
{
Logger.Log("Starting WinNT Bind to {0}",domain);
try
{
var serverPath = String.Format("WinNT://{0}",domain);
Logger.Log("Creating DirectoryEntry object for {0} on domain {1}", login, serverPath);
using (DirectoryEntry de = new DirectoryEntry(serverPath, login, password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing))
{
if (!de.NativeObject.Equals(null))
{
Logger.Log("WinNT Bind Success");
}
else
{
Logger.Log("WinNT Bind Failed");
}
}
}
catch(Exception ex)
{
Logger.Log("{0} occured during WinNT Bind: {1}",ex.GetType().Name,ex.Message);
Logger.Log("Stack: {0}",ex.StackTrace);
}
}
public static void DoLDAPBind(string domain,string login, string password)
{
Logger.Log("Starting LDAP Bind to {0}",domain);
try
{
var serverPath = String.Format("LDAP://{0}",domain);
Logger.Log("Creating DirectoryEntry object for {0} on domain {1}", login, serverPath);
using (DirectoryEntry de = new DirectoryEntry(serverPath, login, password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing))
{
if (!de.NativeObject.Equals(null))
{
Logger.Log("LDAP Bind Success");
}
else
{
Logger.Log("LDAP Bind Failed");
}
}
}
catch(Exception ex)
{
Logger.Log("{0} occured during LDAP Bind: {1}",ex.GetType().Name,ex.Message);
Logger.Log("Stack: {0}",ex.StackTrace);
}
}
As you can see, there is not much code other than using System.DirectoryServices.DirectoryEntry to connect to a DC.
The resulting logfile is (name and domain masked).
6/29/2010 2:52:17 PM: Performing AD
binds for user1 6/29/2010 2:52:17 PM:
Starting LDAP Bind to xxx.xxx
6/29/2010 2:52:17 PM: Creating
DirectoryEntry object for on domain
LDAP://xxx.xxx 6/29/2010 2:52:17 PM:
DirectoryServicesCOMException occured
during LDAP Bind: Logon failure:
unknown user name or bad password.6/29/2010 2:52:17 PM: Stack: at
System.DirectoryServices.DirectoryEntry.Bind(Boolean
throwIfFail) at
System.DirectoryServices.DirectoryEntry.Bind()
at
System.DirectoryServices.DirectoryEntry.get_NativeObject()
at
AdmitOne.Superglue.ActiveDirectoryHelper.DoLDAPBind(String
domain, String login, String password)
in
C:\Projects\Galapagos\branches\Contract\2.0_SN_Peer\Src\Tools\Superglue\ActiveDirectoryHelper.cs:line
47 6/29/2010 2:52:17 PM: Starting
WinNT Bind to xxx.xxx 6/29/2010
2:52:17 PM: Creating DirectoryEntry
object for user1 on domain
WinNT://xxx.xxx 6/29/2010 2:52:18 PM:
WinNT Bind Success
So the same user name fails to bind using LDAP, but succeeds using WinNT!
Locally in our test environment, we don't see this behavior, both LDAP and WinNT succeed with no issues.
So I'm stuck. I'd like to say it's a problem with their AD environment, but without a smoking gun, I can't.
I'm first asking on Stack, to ensure that my bind code is correct. Afterwhich, I'll probably need to reask on Serverfault, which is the more appropriate place to ask for AD specific issues.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明这不是代码问题,而是客户的 AD 环境存在 Kerberos 问题。
具体来说,安全/密封标志指示 LDAP 提供程序仅使用 Kerberos 来安全地协商身份验证。
由于 WinNT 提供程序不支持 Kerberos,因此与 WinNT 提供程序绑定不存在问题。
It turns out this is not a code issue, but instead the customer's AD environment is having issues with Kerberos.
Specifically the Secure/Sealing flags instruct the LDAP provider to use only Kerberos to securely negotiate auth.
Since Kerberos is not supported by the WinNT provider, there is no issue binding with the WinNT provider.