C# 从System.DirectoryServices将StartTLS与LDAP一起使用
我正在尝试连接到需要StartTLS的LDAP服务器,但运气不好-每当我使用SessionOptions.StartTransportLayerSecurity(..)或将SessionOptions.SecureSocketLayer设置为true时,我都会遇到异常 以下是我使用的代码:C# 从System.DirectoryServices将StartTLS与LDAP一起使用,c#,ldap,directoryservices,starttls,C#,Ldap,Directoryservices,Starttls,我正在尝试连接到需要StartTLS的LDAP服务器,但运气不好-每当我使用SessionOptions.StartTransportLayerSecurity(..)或将SessionOptions.SecureSocketLayer设置为true时,我都会遇到异常 以下是我使用的代码: using (var connection = new LdapConnection(new LdapDirectoryIdentifier(config.LdapServer, config.Port, f
using (var connection = new LdapConnection(new LdapDirectoryIdentifier(config.LdapServer, config.Port, false, false)))
{
connection.SessionOptions.ProtocolVersion = 3;
connection.Credential = new NetworkCredential(config.BindDN, config.BindPassword);
connection.SessionOptions.VerifyServerCertificate += (conn, cert) => {return true;};
connection.AuthType = AuthType.Basic;
//connection.SessionOptions.SecureSocketLayer = true;
connection.SessionOptions.StartTransportLayerSecurity(null); // throws here, same if done after bind.
connection.Bind();
... do stuff with connection
}
由此产生的异常是“TlsOperationException:发生了未指定的错误”,这是在调用StartTransportLayerSecurity方法时发生的
我已经针对OpenLDAP服务器和Active Directory对代码进行了测试,但两者都不起作用
有人知道如何让StartTLS与System.DirectoryServices一起工作吗?请阅读本主题:
例19。使用基本身份验证和SSL/TLS绑定到安全端口50001上的ADAM实例
string hostNameAndSSLPort = "sea-dc-02.fabrikam.com:50001";
string userName = "cn=User1,cn=AdamUsers,cn=ap1,dc=fabrikam,dc=com";
string password = "adamPassword01!";
// establish a connection
LdapConnection connection = new LdapConnection(hostNameAndSSLPort);
// create an LdapSessionOptions object to configure session
// settings on the connection.
LdapSessionOptions options = connection.SessionOptions;
options.ProtocolVersion = 3;
options.SecureSocketLayer = true;
connection.AuthType = AuthType.Basic;
NetworkCredential credential =
new NetworkCredential(userName, password);
connection.Credential = credential;
try
{
connection.Bind();
Console.WriteLine("\nUser account {0} validated using " +
"ssl.", userName);
if (options.SecureSocketLayer == true)
{
Console.WriteLine("SSL for encryption is enabled\nSSL information:\n" +
"\tcipher strength: {0}\n" +
"\texchange strength: {1}\n" +
"\tprotocol: {2}\n" +
"\thash strength: {3}\n" +
"\talgorithm: {4}\n",
options.SslInformation.CipherStrength,
options.SslInformation.ExchangeStrength,
options.SslInformation.Protocol,
options.SslInformation.HashStrength,
options.SslInformation.AlgorithmIdentifier);
}
}
catch (LdapException e)
{
Console.WriteLine("\nCredential validation for User " +
"account {0} using ssl failed\n" +
"LdapException: {1}", userName, e.Message);
}
catch (DirectoryOperationException e)
{
Console.WriteLine("\nCredential validation for User " +
"account {0} using ssl failed\n" +
"DirectoryOperationException: {1}", userName, e.Message);
}
下一个示例显示“如何使用TLS进行身份验证和执行任务”
请阅读本主题:
例19。使用基本身份验证和SSL/TLS绑定到安全端口50001上的ADAM实例
string hostNameAndSSLPort = "sea-dc-02.fabrikam.com:50001";
string userName = "cn=User1,cn=AdamUsers,cn=ap1,dc=fabrikam,dc=com";
string password = "adamPassword01!";
// establish a connection
LdapConnection connection = new LdapConnection(hostNameAndSSLPort);
// create an LdapSessionOptions object to configure session
// settings on the connection.
LdapSessionOptions options = connection.SessionOptions;
options.ProtocolVersion = 3;
options.SecureSocketLayer = true;
connection.AuthType = AuthType.Basic;
NetworkCredential credential =
new NetworkCredential(userName, password);
connection.Credential = credential;
try
{
connection.Bind();
Console.WriteLine("\nUser account {0} validated using " +
"ssl.", userName);
if (options.SecureSocketLayer == true)
{
Console.WriteLine("SSL for encryption is enabled\nSSL information:\n" +
"\tcipher strength: {0}\n" +
"\texchange strength: {1}\n" +
"\tprotocol: {2}\n" +
"\thash strength: {3}\n" +
"\talgorithm: {4}\n",
options.SslInformation.CipherStrength,
options.SslInformation.ExchangeStrength,
options.SslInformation.Protocol,
options.SslInformation.HashStrength,
options.SslInformation.AlgorithmIdentifier);
}
}
catch (LdapException e)
{
Console.WriteLine("\nCredential validation for User " +
"account {0} using ssl failed\n" +
"LdapException: {1}", userName, e.Message);
}
catch (DirectoryOperationException e)
{
Console.WriteLine("\nCredential validation for User " +
"account {0} using ssl failed\n" +
"DirectoryOperationException: {1}", userName, e.Message);
}
下一个示例显示“如何使用TLS进行身份验证和执行任务”
在这个问题上做了更多的工作之后,我发现我遇到了几个问题:
connection.SessionOptions.VerifyServerCertificate
+= (conn, cert) => {return true;};
我们在测试时删除了它,因为OpenLDAP服务器使用的是自签名证书,而该证书不在受信任的存储中。重新引入该回调解决了这个问题,尽管我们现在将其设置为可配置选项,即“验证服务器证书Y/N”,因此客户需要选择跳过检查(主要供我们的QA团队使用)
感谢Steffen为我指明了OpenLDAP版本的方向,这使我找到了这个解决方案。在这个问题上做了更多的工作后,我发现我遇到了几个问题:
connection.SessionOptions.VerifyServerCertificate
+= (conn, cert) => {return true;};
我们在测试时删除了它,因为OpenLDAP服务器使用的是自签名证书,而该证书不在受信任的存储中。重新引入该回调解决了这个问题,尽管我们现在将其设置为可配置选项,即“验证服务器证书Y/N”,因此客户需要选择跳过检查(主要供我们的QA团队使用)
感谢Steffen为我指明了OpenLDAP版本的方向,这使我找到了这个解决方案。过去在野外存在大量微妙的LDAP堆栈不兼容,这仍然适用于您的客户可能正在使用的潜在遗留方案 以下是有关OpenLDAP和Microsoft LDAP堆栈之间不兼容的最常见问题(一旦有更多信息可用,我将修改和/或替换这些链接):
- OpenLDAP(在中总结)触发了相应的修补程序:
祝你好运 过去在野外存在大量微妙的LDAP堆栈不兼容,这可能仍然适用于您的客户可能正在使用的潜在遗留方案 以下是有关OpenLDAP和Microsoft LDAP堆栈之间不兼容的最常见问题(一旦有更多信息可用,我将修改和/或替换这些链接):
- OpenLDAP(在中总结)触发了相应的修补程序:
祝你好运 您能否指定OpenLDAP、Active Directory的具体版本,特别是此处涉及的客户端和服务器的操作系统,以缩小范围?过去在野外存在大量微妙的LDAP堆栈不兼容,这可能仍然适用于您的客户可能使用的潜在遗留方案。嗨,Steffen,信息是OpenLDAP 2.4.18,服务器和客户端的FreeBSD是Windows server 2008 r2计算机(客户端代码托管在ASP.Net应用程序中,.Net Framework 3.5 SP1). 通过进一步搜索LDAP版本,我找到了一些关于这个主题的博客文章,包括:-这帮助我找到了问题的根源。我将尝试并鼓励用户升级到最新的OpenLDAP,因为我认为这个问题可能在以后的版本中得到修复(他们的版本非常旧,于2009年9月6日发布于Sun),感谢后续信息,这将有助于以后的读者解决类似的问题(+1)!我已经相应地…您可以指定OpenLDAP、Active Directory的具体版本,特别是此处涉及的客户端和服务器的操作系统,以缩小范围吗?过去,在野外存在大量微妙的LDAP堆栈不兼容,这仍然适用于客户可能使用的潜在遗留方案。嗨,Steffen,信息是OpenLDAP 2.4.18,服务器和客户端的FreeBSD是Windows