Kem*_*eth 6 c# ssl active-directory
我正在尝试从LDAP获取根DirectoryEntry,以便我可以显示它的一个很好的图形树视图.
这一切在正常连接下都能很好地工作,但我无法使用SSL.
var root = this.checkBoxSSL.Checked
? new DirectoryEntry("LDAP://" + this.textBoxServer.Text,
this.textBoxUsername.Text,
this.textBoxPassword.Text,
AuthenticationTypes.SecureSocketsLayer)
: new DirectoryEntry("LDAP://" + this.textBoxServer.Text,
this.textBoxUsername.Text,
this.textBoxPassword.Text);
var dn = root.Properties["distinguishedName"].Value;
Run Code Online (Sandbox Code Playgroud)
等等...
但我得到一个"服务器无法运行"的例外.这一切似乎都归结为绑定过程.基于互联网研究,它可能是证书和/或身份验证方法(NTLM等)的问题.
那么如何才能通过SSL获得有效的DirectoryEntry?
我愿意接受替代解决方案,只要我可以检索所需节点的所有LDAP属性.(Root,DC,OU,CN,组和用户)
编辑:因为它似乎问题归结为SSL证书.我们只有一个自签名证书atm.而且这似乎被.NET默认拒绝.我们稍后会尝试使用正确签名的证书,但我可能需要能够处理自签名证书.
这是我对证书的了解有限的地方.我正在探索一种不同的代码解决方案,因为它似乎是唯一允许我影响整个证书处理的解决方案:
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new System.Security.Cryptography.X509Certificates.X509Certificate2();
cert.Import("..\\..\\test certificate.cer");
LdapConnection con = new LdapConnection("ip:636");
con.Credential = new NetworkCredential("un", "pw");
con.AuthType = AuthType.Ntlm;
con.SessionOptions.SecureSocketLayer = true;
con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback((ldapcon, cer) => {
var cer2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(cer);
StringBuilder strb = new StringBuilder();
strb.AppendFormat("{0} {1} matches: {2}\n", "Subject", cert.Subject, cert.Subject.Equals(cer2.Subject));
strb.AppendFormat("{0} {1} matches: {2}\n", "Cert Hash", cert.GetCertHashString(), Enumerable.SequenceEqual<byte>(cer.GetCertHash(), cert.GetCertHash()));
strb.AppendFormat("{0} matches: {2}\n", "Public Key", cert.GetPublicKeyString(), Enumerable.SequenceEqual<byte>(cer.GetPublicKey(), cert.GetPublicKey()));
strb.AppendFormat("{0}: {1}, {2}", "Verification", cert.Verify(), cer2.Verify());
var res = MessageBox.Show(strb.ToString(),
"Allow certificate?", MessageBoxButtons.YesNo);
return res == System.Windows.Forms.DialogResult.Yes;
});
con.Bind();
Run Code Online (Sandbox Code Playgroud)
本质上,如果VerifyServerCertificateCallback返回true,则连接成功,如果返回连接失败,则连接失败,其异常与我尝试过的任何其他解决方案相同.
奇怪的是,安装AD证书或AD控制器的根证书都没有帮助其他解决方案,但它确实改变了Verify()方法的结果.
我必须在回调中对证书执行哪些检查才能保持SSL连接的神圣性?
小智 7
布莱恩·德斯蒙德就快到了。您需要在 DirectoryEntry AuthenticationType 中设置 2 个标志:
AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.SecureSocketsLayer | 身份验证类型.安全
例子:
new DirectoryEntry("LDAP://" + this.textBoxServer.Text + ":636",
this.textBoxUsername.Text,
this.textBoxPassword.Text,
AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.Secure)
Run Code Online (Sandbox Code Playgroud)
我建议你使用PrincipalContext的System.DirectoryServices.AccountManagement.初始化将如下所示:
PrincipalContext context = new PrincipalContext(
ContextType.Domain, NAME_OF_THE_DOMAIN + ":636",
null,
ContextOptions.SecureSocketLayer | ContextOptions.Negotiate,
this.textBoxUsername.Text,
this.textBoxPassword.Text);
Run Code Online (Sandbox Code Playgroud)
之后你可以搜索a UserPrincipal和它DistinguishedName:
string dn = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, this.textBoxUsername.Text).DistinguishedName;
Run Code Online (Sandbox Code Playgroud)
如果你想通过AD树进行迭代,只需在以下帮助下执行以下操作PrincipalSearcher:
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
//DO watherever you want
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
首先,您应该确保您的帐户和密码可用。使用ldp.exe工具检查帐户是否可用。
那么也许您可以尝试如下所示,请使用 LDAP:// 而不是 LDAPS://
LdapConnection conn = new LdapConnection("xx1.bb.aa.com:636");
var op = conn.SessionOptions;
op.ProtocolVersion = 3;
op.SecureSocketLayer = true;
op.VerifyServerCertificate += delegate { return true; };
conn.AuthType = AuthType.Negotiate;
var cred = new NetworkCredential("accountname", "password");
//conn.Credential = cred;
try
{
conn.Bind(cred);
if (op.SecureSocketLayer)
{
Console.WriteLine("SSL for encryption is enabled - SSL information:");
}
}
catch (Exception ex)
{
throw;
}
Run Code Online (Sandbox Code Playgroud)
或者:
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://xx1.bb.aa.com:636",
"ldapsusername", "password", AuthenticationTypes.SecureSocketsLayer);
//directoryEntry.Options
DirectorySearcher searcher = new DirectorySearcher(directoryEntry)
{
PageSize = int.MaxValue,
Filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=hp.wang))"
};
searcher.PropertiesToLoad.Add("sn");
var result = searcher.FindOne();
if (result == null)
{
return; // Or whatever you need to do in this case
}
string surname;
if (result.Properties.Contains("sn"))
{
surname = result.Properties["sn"][0].ToString();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16703 次 |
| 最近记录: |