插入智能卡的PrincipalContext

时间:2017-11-07 14:50:03

标签: c# .net active-directory account-management

我们一直在使用一个应用程序,它使用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会话相关联。当我们不启用加密时,该问题不存在。但加密是强制性的。

之前是否有人遇到此问题?资源似乎有限。我能找到的最近的是:

https://connect.microsoft.com/VisualStudio/feedback/details/3100569/initializing-contextoptions-does-not-work-in-system-directoryservices-accountmanagement-principalcontext-constructor

提前致谢

1 个答案:

答案 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对象时完成。