Bryan

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            37 Posts :: 3 Stories :: 24 Comments :: 0 Trackbacks
          The primary reason that JNDI is commonly-used for directory-enabled applications is that it is part of the core Java platform. In fact, that is perhaps the only reason for its popularity, since the API itself is absolutely horrible. It is very abstract (in fact, it is intended for use in communicating with a number of different types of systems, so it really isn't an LDAP API as much as an API that happens to provide LDAP support), which means that performing simple tasks often require significantly more code than should be required, and that it uses terminology that can be extremely confusing (e.g., in JNDI, the "bind" method is used to add an entry to the directory rather than performing an LDAP bind operation). Further, the abstract nature of the API may make some tasks either difficult (e.g., performing an LDAP compare operation) or impossible (e.g., retrieving the result code from an operation). Finally, JNDI provides virtually no support for anything but the most basic functionality. It provides no facilities for interacting with data in LDIF form, or for performing ASN.1 encoding/decoding needed to support development of custom controls and extensions.

          Establishing a Connection

          This section will demonstrate the process for establishing a simple LDAPv3 connection (with no SSL or other security) and performing a simple bind operation.

          JNDI

          In JNDI, when you wish to establish a connection to an LDAP directory server, you should create an InitialLdapContext object. This can be quite a daunting task, because the only way that you have to specify the target server, whether or not to use SSL or some other security mechanism, whether or not to authenticate, etc. is by providing a set of properties. There aren't any convenience methods to help you figure out what those properties might be (although there are constants in some cases), so you have to look through the documentation to try to find them, and in fact some of these properties and/or values use "com.sun.*" prefixes, so it isn't even clear whether they are safe to use in code that might run on Java implementations provided by vendors other than Sun.

          Here is an example of the work required to do this in JNDI:

          Properties env = new Properties();
          env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
          env.put(Context.PROVIDER_URL, "ldap://server.example.com:389/");
          env.put(Context.SECURITY_PRINCIPAL,
                  "uid=test.user,ou=People,dc=example,dc=com");
          env.put(Context.SECURITY_CREDENTIALS, "password");
          env.put("java.naming.ldap.version", "3");
          
          LdapContext connection = new InitialLdapContext(env, null);
          

          Performing a Search Operation

          This section will demonstrate the process for performing a search to find a user entry and then retrieve that user's e-mail address from the mail attribute. In each of these cases, it will be assumed that only one entry will be returned, so we don't need to worry about the possibility of multiple entries matching the search criteria.

          JNDI

          The JNDI "search" methods may be used to perform searches in the directory, and the simplest of these in most cases is the variant that takes string representations of the base DN and filter and a SearchControls object. This is another case where JNDI suffers from a poor choice of terminology because "controls" in this case does not have anything at all to do with LDAP controls but rather with a set of miscellaneous options used to perform the search (e.g., the search scope, attributes to return, size and time limits, etc.).

          Something else that directory developers may find confusing is that the methods used to get attribute values have a generic return type of Object. It is not clear from the JNDI specification whether these objects will always be strings or whether they may be other types of objects. Further, it is not necessarily clear if it is possible to obtain the values in any other form (e.g., the raw bytes that make up the value).

          The following code illustrates the process for performing the desired search processing in JNDI:

          SearchControls searchControls = new SearchControls();
          searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
          searchControls.setReturningAttributes(new String[] { "mail" });
          
          String mail = null;
          NamingEnumeration<SearchResult> results =
               connection.search("dc=example,dc=com", "(uid=john.doe)", searchControls);
          while (results.hasMore())
          {
            SearchResult result = results.next();
            Attributes attributes = result.getAttributes();
            Attribute attribute = attributes.get("mail");
            if (attribute != null)
            {
              Object o = attribute.get();
              if (o != null)
              {
                mail = String.valueOf(o);
              }
            }
          }
          

          Performing an Add Operation

          This section will demonstrate the process for adding a simple entry to the server. In this case, the entry added will have the following LDIF representation:

          dn: dc=example,dc=com
          objectClass: top
          objectClass: domain
          dc: example
          

          JNDI

          As noted above, JNDI uses the poorly-named "bind" method to add an entry to the server (and "unbind" to delete an entry). The basic reasoning for this is that it is trying to associate the provided set of data (the attributes) with a name (the DN), but this can be very confusing and frustrating for developers familiar with LDAP directories but not very familiar with JNDI because obviously the terms "bind" and "unbind" have very different meanings in LDAP. Another nit with JNDI is that Attributes and Attribute are interfaces rather than classes, so it is necessary to create BasicAttributes and BasicAttribute objects instead, and it appears that there is no way to create an attribute with multiple values so it is first necessary to create a BasicAttribute with a single value and then add additional values to it.

          The code to use to add an entry in JNDI is as follows:

          Attributes attributes = new BasicAttributes();
          
          Attribute objectClassAttribute = new BasicAttribute("objectClass", "top");
          objectClassAttribute.add("domain");
          attributes.put(objectClassAttribute);
          
          attributes.put("dc", "example");
          
          connection.bind("dc=example,dc=com", null, attr
          ibutes);
          
          posted on 2012-06-16 17:13 Life is no respector of any genius. 閱讀(543) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 襄垣县| 沂南县| 三原县| 霸州市| 嘉义县| 兴仁县| 胶南市| 鹤壁市| 台中市| 喀什市| 漠河县| 贡觉县| 武城县| 施秉县| 于田县| 松溪县| 中方县| 溆浦县| 宜良县| 甘德县| 抚顺市| 财经| 临猗县| 阳原县| 达拉特旗| 水城县| 乐业县| 江山市| 馆陶县| 镇康县| 新邵县| 土默特右旗| 南昌县| 宕昌县| 和硕县| 武汉市| 山丹县| 北辰区| 茌平县| 大方县| 中宁县|