[英].NET Core - Novell LDAP/AD - Group search for a user that he belongs to - Has anybody made it work?
[英]Novell LDAP C# - Novell.Directory.Ldap - Has anybody made it work?
我正在尝试使用 Novell (Novell.Directory.Ldap) 发布的库。 版本 2.1.10。
到目前为止我所做的:
我测试了与应用程序( LdapBrowser )的连接并且它正在工作,所以它不是通信问题。
它是用 Mono 编译的,但我正在使用 Visual Studio。 所以创建了一个带有源的项目。 我还引用了 Mono.Security,因为项目依赖于它。
我在连接的错误捕获部分评论了一个调用 (freeWriteSemaphore(semId);),因为它抛出了更多异常。 我检查了那个调用做了什么,它只是一个错误跟踪机制。
我遵循了 Novell ( http://www.novell.com/coolsolutions/feature/11204.html ) 文档中提供的基本步骤。
// 创建一个 LdapConnection 实例
LdapConnection ldapConn= new LdapConnection(); ldapConn.SecureSocketLayer = ldapPort == 636;
//Connect 函数将创建一个到服务器的套接字连接
ldapConn.Connect(ldapHost,ldapPort);
//绑定函数将用户对象Credentials绑定到服务器
ldapConn.Bind(userDN,userPasswd);
现在它在 Bind() 函数处崩溃。 我收到错误 91。
那么,有没有人使用过这个库并看到它工作? 如果是这样,你做了什么使它工作,是否需要一些特殊的配置? 有没有办法让它在没有 Mono 的 .NET 环境中工作(我可以引用 Mono dll,但我不希望它安装在服务器上)?
(更新)连接在端口 636 上,因此使用 SSL。 我检查了 WireShark 的通信并与我从 LDAP 浏览器获得的内容进行了比较。 我已经看到传递 SSL 证书的步骤不是由 LDAP 库完成的。 那么,让它做它应该做的最好的方法是什么?
(更新)我检查了文档,它表明它不支持 SSL。 http://www.novell.com/coolsolutions/feature/11204.html
使用 LdapConnection.Bind() 对 LDAP 服务器进行身份验证。 我们仅支持明文身份验证。 尚未添加 SSL/TLS 支持。
但是文档的日期是 2004 年,从那时起,已经进行了许多更新。 并且库中有一个参数来定义连接是否使用 SSL。 所以现在我很困惑。
(更新)找到了更新的文档: http : //developer.novell.com/documentation//ldapcsharp/index.html?page=/ documentation //ldapcsharp/cnet/data/bqwa5p0.html 。 建立 SSL 连接的方式是在服务器上注册证书。 问题是我正在做的事情没有绑定到特定的 Novell 服务器,因此必须动态获取证书。
我是来寻找类似问题的解决方案的。 使用 Novell 网站上的相同代码时,我的绑定命令也会失败。 对我有用的解决方案是添加动态证书验证回调。 你可以在这里阅读它。
// Creating an LdapConnection instance
LdapConnection ldapConn = new LdapConnection();
ldapConn.SecureSocketLayer = true;
ldapConn.UserDefinedServerCertValidationDelegate += new
CertificateValidationCallback(MySSLHandler);
//Connect function will create a socket connection to the server
ldapConn.Connect(ldapHost, ldapPort);
//Bind function will Bind the user object Credentials to the Server
ldapConn.Bind(userDN, userPasswd);
// Searches in the Marketing container and return all child entries just below this
//container i.e. Single level search
LdapSearchResults lsc = ldapConn.Search("ou=users,o=uga",
LdapConnection.SCOPE_SUB,
"objectClass=*",
null,
false);
while (lsc.hasMore())
{
LdapEntry nextEntry = null;
try
{
nextEntry = lsc.next();
}
catch (LdapException e)
{
Console.WriteLine("Error: " + e.LdapErrorMessage);
// Exception is thrown, go for next entry
continue;
}
Console.WriteLine("\n" + nextEntry.DN);
LdapAttributeSet attributeSet = nextEntry.getAttributeSet();
System.Collections.IEnumerator ienum = attributeSet.GetEnumerator();
while (ienum.MoveNext())
{
LdapAttribute attribute = (LdapAttribute)ienum.Current;
string attributeName = attribute.Name;
string attributeVal = attribute.StringValue;
Console.WriteLine(attributeName + "value:" + attributeVal);
}
}
ldapConn.Disconnect();
Console.ReadKey();
}
public static bool MySSLHandler(Syscert.X509Certificate certificate,
int[] certificateErrors)
{
X509Store store = null;
X509Stores stores = X509StoreManager.CurrentUser;
//string input;
store = stores.TrustedRoot;
X509Certificate x509 = null;
X509CertificateCollection coll = new X509CertificateCollection();
byte[] data = certificate.GetRawCertData();
if (data != null)
x509 = new X509Certificate(data);
return true;
}
我终于找到了一种方法来完成这项工作。
首先,这些帖子帮助我走上了正轨: http : //directoryprogramming.net/forums/thread/788.aspx
其次,我得到了 Novell LDAP 库的编译 dll 并使用了 Mono.Security.Dll。
解决办法:
我在代码中添加了这个函数
// This is the Callback handler - after "Binding" this is called
public bool MySSLHandler(Syscert.X509Certificate certificate, int[] certificateErrors)
{
X509Store store = null;
X509Stores stores = X509StoreManager.LocalMachine;
store = stores.TrustedRoot;
//Import the details of the certificate from the server.
X509Certificate x509 = null;
X509CertificateCollection coll = new X509CertificateCollection();
byte[] data = certificate.GetRawCertData();
if (data != null)
x509 = new X509Certificate(data);
//List the details of the Server
//if (bindCount == 1)
//{
Response.Write("<b><u>CERTIFICATE DETAILS:</b></u> <br>");
Response.Write(" Self Signed = " + x509.IsSelfSigned + " X.509 version=" + x509.Version + "<br>");
Response.Write(" Serial Number: " + CryptoConvert.ToHex(x509.SerialNumber) + "<br>");
Response.Write(" Issuer Name: " + x509.IssuerName.ToString() + "<br>");
Response.Write(" Subject Name: " + x509.SubjectName.ToString() + "<br>");
Response.Write(" Valid From: " + x509.ValidFrom.ToString() + "<br>");
Response.Write(" Valid Until: " + x509.ValidUntil.ToString() + "<br>");
Response.Write(" Unique Hash: " + CryptoConvert.ToHex(x509.Hash).ToString() + "<br>");
// }
bHowToProceed = true;
if (bHowToProceed == true)
{
//Add the certificate to the store. This is \Documents and Settings\program data\.mono. . .
if (x509 != null)
coll.Add(x509);
store.Import(x509);
if (bindCount == 1)
removeFlag = true;
}
if (bHowToProceed == false)
{
//Remove the certificate added from the store.
if (removeFlag == true && bindCount > 1)
{
foreach (X509Certificate xt509 in store.Certificates)
{
if (CryptoConvert.ToHex(xt509.Hash) == CryptoConvert.ToHex(x509.Hash))
{
store.Remove(x509);
}
}
}
Response.Write("SSL Bind Failed.");
}
return bHowToProceed;
}
我在绑定过程中使用了它
// Create Connection
LdapConnection conn = new LdapConnection();
conn.SecureSocketLayer = true;
Response.Write("Connecting to:" + ldapHost);
conn.UserDefinedServerCertValidationDelegate += new
CertificateValidationCallback(MySSLHandler);
if (bHowToProceed == false)
conn.Disconnect();
if (bHowToProceed == true)
{
conn.Connect(ldapHost, ldapPort);
conn.Bind(loginDN, password);
Response.Write(" SSL Bind Successfull ");
conn.Disconnect();
}
quit = false;
关键是使用 SSL Handler 动态获取证书,并使用 X509StoreManager.LocalMachine 以便在网站运行时能够保存和获取证书。
我致力于 Forefront Identity Manager 集成。 所以我写的代码总是来自几个调用客户端。 如果您尝试打包应用程序以供“任何地方”使用,这可能不合适。
我只是想用一个简单的解决方案来更新这个线程,这些解决方案适用于启用了默认 TLS/SSL“需要保密”选项的 Novell 服务器。
1) 确保您也从您绑定的 Novell 服务器上获取 SSL 证书,并将这些证书注册到正在执行的客户端/服务器上的可信存储中。 通常有两个 1 用于 IP 和取决于您将调用的主机名(最好使用 DNS)
2) 使用 System.DirectoryServices 导入以下/添加引用; 使用 System.DirectoryServices.Protocols;
3)这是一个片段。 确保选择 AuthenticationTypes.SecureSocketsLayer 这是关键。
// serverAddress = Server IP or DNS (Match SSL certificate)
// ObjectDN = The DN of the user you are binding to
// userName = Account which will be used to make the bind
// password = password of the user which will make the bind
// value = The value you wish to add to the attribute
// Connect to the user in LDAP
DirectoryEntry entry = new DirectoryEntry("LDAP://" + serverAddress + "/" + ObjectDN + ""
, userName
, password
, AuthenticationTypes.SecureSocketsLayer);
// Write the Updated attribute
entry.Properties["attribute"].Value = value;
// Read back the updated Attribute into a label
label.Text = entry.Properties["attribute"].Value.ToString();
91 是“无法连接”。 尝试将服务器设置为“ldap://xxxx”格式,检查 userDN 是否设置正确(包括域等)。
我经常使用WireShark来查看网络级别发生了什么(它知道 LDAP 协议)。
我想我可能已经在另一个问题中向其他人提供了这个答案。
[有关 LDAP 的其他问题][1]
我认为有两个问题:1)你想做什么类型的绑定? SSL? 清晰的文字? 匿名?
2) 如何在 eDirectory 端为 LDAP 绑定配置?
LDAP 浏览器工具,您指的是此链接中的工具吗? 免费 LDAP 浏览器
在 eDirectory 方面,它们可以要求所有 LDAP 通信都使用 TLS,并且可以禁止匿名绑定。
您能否要求另一端的人启用 LDAP 跟踪(使用 Dstrace 并启用 +LDAP 选项,有关如何在 Novell eDirectory 上使用 Dstrace 的一些链接请查看:不同类型的 Dstrace 捕获和了解身份管理器的 DS 跟踪。)
这通常会显示一条错误消息,让您有所启发。
我的猜测是 Require TLS 已启用,并且您可能没有成功进行 SSL 绑定。
如果是这样,请尝试在端口 636 上连接,启用 SSL,并为您尝试登录的用户提供完全限定的 DN。
如果您尝试启用 SSL,并且没有收到关于接受树 CA 的受信任根证书的弹出框,则可能是 eDirectory 服务器用户的 CA 或 SSL 证书已过期或损坏。 (造成这种情况的原因有很多,这些原因可能很常见,只需花点时间即可解决)。
通常在 Dstrace 中,如果出现问题,您会看到有关 SSL 证书的错误。 从 Novell Identity Manager 的角度来看,过期证书的一个示例在这篇文章中:证书过期以及有关如何修复证书的一些详细信息。
下一个可能是您指定的 DN 不太正确。
如果您需要更多帮助,请告诉我。
按照我之前的帖子 - 如果您必须使用安全连接,请尝试使用 ldaps:// 作为服务器地址的前缀。
如果没有 SSL/TLS 支持,您可以试试这个- OpenLDAP 库的指南和 .NET 包装器。
重要的一点 - OpenLDAP 中有 TLS 安全级别的设置,因此如果您的 LDAP 服务器具有自签名证书,您要么必须在客户端导入它,要么将 TLS 设置为不检查签名权限*这当然不太安全)。
我已经经历过这个场景,对我来说是在 Kubernetes 容器中运行的 Novell LDAP 服务。 我尝试将 CA 证书添加到 Mono 信任库,这将在 linux 容器中的“/usr/share/.mono/certs/Trust”中添加文件。 但是没有任何效果,对于 LDAP 636 端口,Novell 连接仍然没有成功。
最后我让它以下面的方式工作:
LdapConnection Connection = new LdapConnection();
Connection.SecureSocketLayer = true;
Connection.UserDefinedServerCertValidationDelegate += new
Novell.Directory.Ldap.RemoteCertificateValidationCallback(LdapSSLHandler);
public bool LdapSSLHandler(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == sslPolicyErrors.None)
{
return true; //Is valid
}
if (certificate.GetCertHashString() == "YOUR CERTIFICATE HASH KEY") // Thumbprint value of the certificate
{
return true;
}
return false;
}
UserDefinedServerCertValidationDelegate 已过时,因此如果它是无效 ssl 证书的问题,您可以通过以下方式跳过证书验证:
LdapConnectionOptions options = new LdapConnectionOptions()
.ConfigureRemoteCertificateValidationCallback(new CertCallback((a, b, c, d) => true))
.UseSsl();
LdapConnection connection = new LdapConnection(options);
connection.Connect(...);
但是,您应该检查忽略证书是否是您应用程序的安全解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.