我们一直在使用一个应用程序,它使用System.DirectoryServices.AccountManagement与Active目录(域上下文)进行通信。
ContextOptions options = ContextOptions.Negotiate |
ContextOptions.SecureSocketLayer;
Using(PrincipalContext adContext = new PrincipalContext(ContextType.Domain, "AD.DOMAIN", "DC=AD,DC=intranet", options))
{
//Do stuff
}
这一切正常,直到我们插入智能卡。只要我们插入带有用户证书的智能卡,它就会在遇到PrincipalContext构造函数时立即提示输入智能卡。取消时,应用程序将崩溃。当输入正确的引脚时,它会一直持续提示。
它似乎与在后台设置的TLS会话相关联。当我们不启用加密时,该问题不存在。但加密是强制性的。
之前是否有人遇到此问题?资源似乎有限。我能找到的最近的是:
提前致谢
答案 0 :(得分:0)
PrincipalContext
利用内部类CredentialValidator
在LDAP绑定期间进行身份验证。
private bool BindLdap(NetworkCredential creds, ContextOptions contextOptions)
{
LdapConnection current = (LdapConnection) null;
...
current = new LdapConnection(this.directoryIdent);
...
try
{
current.SessionOptions.FastConcurrentBind();
方法FastConcurrentBind
找到证书,并且在连接选项中启用了SSL,它会要求输入PIN。
如果不支持快速绑定,则调用Bind
并执行相同的操作:
private void lockedLdapBind(
LdapConnection current,
NetworkCredential creds,
ContextOptions contextOptions)
{
current.AuthType =
(ContextOptions.SimpleBind & contextOptions) > (ContextOptions) 0
? AuthType.Basic
: AuthType.Negotiate;
current.SessionOptions.Signing =
(ContextOptions.Signing & contextOptions) > (ContextOptions) 0;
current.SessionOptions.Sealing =
(ContextOptions.Sealing & contextOptions) > (ContextOptions) 0;
if (creds.UserName == null && creds.Password == null)
current.Bind();
else
current.Bind(creds);
}
为了防止这种情况,必须像这样修改会话选项
current.SessionOptions.QueryClientCertificate =
new QueryClientCertificateCallback((a,b) => null);
问题在于,无法从外部对内部类进行此操作。
这只能在手动构建LdapConnection对象时完成。