在使用托管ODP.NET时,如何从C#查询LDAP以解析Oracle TNS主机名?

Neo*_*Neo 6 c# oracle tnsnames ldap directoryentry

继我之前的问题,我设法在Oracle论坛的帮助下回答了自己,我现在有另一个问题,从前一个问题开始(提供给后台).

我希望直接从我的C#代码查询LDAP,以执行Oracle TNS主机名的LDAP查找,以获取连接字符串.这通常存储在tnsnames.ora中,我的组织使用LDAP(通过ldap.ora)使用Active Directory从LDAP服务器解析主机名.

但是,我在我的C#应用​​程序中使用ODP.NET,托管驱动程序测试版(Oracle.ManagedDataAccess.dll),它不支持LDAP,如前面提到的Oracle论坛回复所指出的发行说明中所述.这就是我希望直接从C#查询LDAP的原因.

我在这里找到了一种方法,使用DirectoryEntryDirectorySearcher,但我不知道要把什么作为参数DirectorySearcher.我可以访问ldap.ora,其格式如下:

#LDAP.ORA配置
#由Oracle配置工具生成.
DEFAULT_ADMIN_CONTEXT ="dc = xx,dc = mycompany,dc = com"
DIRECTORY_SERVERS =(ldap_server1.mycompany.com:389:636,ldap_server2.mycompany.com:389:636, ...)DIRECTORY_SERVER_TYPE = OID

但是,如何将其映射到在我的C#代码中设置LDAP查询?

Neo*_*Neo 5

除了我在已接受的答案中的第二条评论之外,这是用于执行 LDAP 查找的代码,它改进了我在这里找到的原始版本。它还处理ldap.ora文件中的服务器列表,其中包括多个分隔的端口号。

private static string ResolveServiceNameLdap(string serviceName)
{
    string tnsAdminPath = Path.Combine(@"C:\Apps\oracle\network\admin", "ldap.ora");
    string connectionString = string.Empty;

    // ldap.ora can contain many LDAP servers
    IEnumerable<string> directoryServers = null;

    if (File.Exists(tnsAdminPath))
    {
        string defaultAdminContext = string.Empty;

        using (var sr = File.OpenText(tnsAdminPath))
        {
            string line;

            while ((line = sr.ReadLine()) != null)
            {
                // Ignore commetns
                if (line.StartsWith("#"))
                {
                    continue;
                }

                // Ignore empty lines
                if (line == string.Empty)
                {
                    continue;
                }

                // If line starts with DEFAULT_ADMIN_CONTEXT then get its value
                if (line.StartsWith("DEFAULT_ADMIN_CONTEXT"))
                {
                    defaultAdminContext = line.Substring(line.IndexOf('=') + 1).Trim(new[] {'\"', ' '});
                }

                // If line starts with DIRECTORY_SERVERS then get its value
                if (line.StartsWith("DIRECTORY_SERVERS"))
                {
                    string[] serversPorts = line.Substring(line.IndexOf('=') + 1).Trim(new[] {'(', ')', ' '}).Split(',');
                    directoryServers = serversPorts.SelectMany(x =>
                    {
                        // If the server includes multiple port numbers, this needs to be handled
                        string[] serverPorts = x.Split(':');
                        if (serverPorts.Count() > 1)
                        {
                            return serverPorts.Skip(1).Select(y => string.Format("{0}:{1}", serverPorts.First(), y));
                        }

                        return new[] {x};
                    });
                }
            }
        }

        // Iterate through each LDAP server, and try to connect
        foreach (string directoryServer in directoryServers)
        {
            // Try to connect to LDAP server with using default admin contact
            try
            {
                var directoryEntry = new DirectoryEntry("LDAP://" + directoryServer + "/" + defaultAdminContext, null, null, AuthenticationTypes.Anonymous);
                var directorySearcher = new DirectorySearcher(directoryEntry, "(&(objectclass=orclNetService)(cn=" + serviceName + "))", new[] { "orclnetdescstring" }, SearchScope.Subtree);

                SearchResult searchResult = directorySearcher.FindOne();

                var value = searchResult.Properties["orclnetdescstring"][0] as byte[];

                if (value != null)
                {
                    connectionString = Encoding.Default.GetString(value);
                }

                // If the connection was successful, then not necessary to try other LDAP servers
                break;
            }
            catch
            {
                // If the connection to LDAP server not successful, try to connect to the next LDAP server
                continue;
            }
        }

        // If casting was not successful, or not found any TNS value, then result is an error message
        if (string.IsNullOrEmpty(connectionString))
        {
            connectionString = "TNS value not found in LDAP";
        }
    }
    else
    {
        // If ldap.ora doesn't exist, then return error message
        connectionString = "ldap.ora not found";
    }

    return connectionString;
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*See 1

根据我在Oracle Database Name Resolution with OpenLDAP中发现的内容来看,代码应该如下所示:

string directoryServer = "ldap_server1.mycompany.com:389";
string defaultAdminContext = "dc=xx,dc=mycompany,dc=com";
string oracleHostEntryPath = string.Format("LDAP://{0}/cn=OracleContext,{1}", directoryServer, defaultAdminContext);

var directoryEntry = new DirectoryEntry(oracleHostEntryPath) {AuthenticationType = AuthenticationTypes.None};
var directorySearcher = new DirectorySearcher(directoryEntry, "(&(objectclass=orclNetService)(cn=ABCDEFG1))", new[] { "orclnetdescstring" }, SearchScope.Subtree);

string oracleNetDescription = Encoding.Default.GetString(des.FindOne().Properties["orclnetdescstring"][0] as byte[]);
Run Code Online (Sandbox Code Playgroud)