Advice for LDAP Application Developers

   

As with most projects, the process of developing an LDAP directory-enabled application is filled with many choices. You can save yourself a lot of grief if you plan ahead and think about how your application will interact with the directory service and other applications. This section provides some advice to help you develop good LDAP applications. Additional information on data- related design considerations can be found in Chapter 18, Maintaining Data.

Striving to Fit In

A common mistake made by new LDAP application developers is to treat the directory as a private application-specific store. Although in rare cases this approach might be valid, most LDAP directories focus on sharing information among applications, end users, and administrators. Also keep in mind that the design of the directory may be altered in the future to meet the needs of other applications or to accommodate organizational changes.

You should design and write your application to assume as little as possible about the directory design and to coexist well with other applications ”including ones that have not yet been written. To accomplish these goals, follow these guidelines when designing and implementing your application:

  • Use standard schema elements whenever practical. Using standard schema elements promotes interoperability and makes it easier to coexist with other applications, while also helping to simplify directory service software upgrades.

  • When extending schemas, follow the procedures outlined in Chapter 8, Schema Design. It is best to do these two things: (1) create auxiliary object classes so that you can add attributes to existing objects such as persons and (2) use an application- or organization-specific prefix when naming new attributes and object classes so that you avoid naming conflicts.

  • Avoid using mandatory attributes when you define your auxiliary object classes. Suppose another application includes the same attribute type as an optional one in its own auxiliary object class. The application may encounter an error when it tries to add its own object class and attributes to an entry because it may not realize that the attribute is mandatory.

  • Assume as little as possible about the directory namespace, topology, replication, and security design. Minimizing assumptions aids coexistence and helps your application continue to work when changes are made to the directory service deployment. Ideally you should anticipate what kind of directory design changes will affect your application and provide configuration settings or built-in intelligence to avoid problems resulting from such changes.

The key to developing an application that coexists well with other applications and can survive directory design changes is in knowing when it is OK to make assumptions. For example, it is probably unacceptable to assume much about how the people and group entries are arranged in the directory information tree (DIT). On the other hand, it is probably OK for your application to dictate the DIT structure within a portion of the directory namespace that it uses to store its own application-specific configuration information.

Tip

Make your application as configurable as possible with respect to how it uses the directory service. Do not hardwire knowledge of the DIT structure, access control rules, or other key parts of the directory design into your application. If you do not expect certain things to change, it is OK to make them somewhat difficult to reconfigure. However, it is important to ensure that there is some way to change the configuration without rewriting or recompiling the application. Otherwise, if a critical directory-related assumption you made ceased to hold true, you would need to modify the application and distribute new copies everywhere. Examples of techniques you can use to build a flexible application include using configuration files or templates for directory-related settings and writing your application so that it reads schema information from the directory service itself.


Communicating Your Application's Directory Needs

As part of your application design process, document how the application interacts with the directory service. Share this information with the people responsible for the design and deployment of the directory service. Sometimes deployment of a new application requires modifications to the directory design or software upgrades, both of which may be perfectly acceptable to directory administrators if known in advance.

The directory administrators should be made aware of any anticipated directory changes as soon as possible so that the required planning and deployment tasks can be handled before your application is deployed. Some of the things you should communicate to them are

  • Schema extensions required for your application.

  • Security and access control changes needed to support your application.

  • Privacy issues surrounding new data that your application may introduce into the directory.

  • Additional directory management tasks required for your application. For example, it might make sense to extend certain existing administrative tools to support a new attribute used by your application.

  • Data integration requirements for the application. For example, you may need to establish additional data synchronization procedures with nondirectory data sources to obtain some of the entries and attribute values needed by your application.

  • Special LDAP protocol features you rely on. For example, you may be planning to use an LDAPv3 protocol extension that is new enough to require an upgrade of the directory server software. Sometimes such a feature may be required for your application, but if possible, try to create a mode in which the application works in the absence of the extension (perhaps with some loss of functionality). Doing so will ease deployment and allow a phased approach if directory server software upgrades are needed.

  • An estimate of the additional load the application will impose on the service. This is typically measured in terms of the number of LDAP operations performed in a given time period. Don't forget to estimate peak loads and consider each operation separately. For example, search operations typically can be handled more quickly by an LDAP server than modify or add operations can.

  • Server configuration changes required by your application, such as indexing of additional attributes.

Designing for Good Performance and Scalability

No two applications, and no two directory deployments, have the same performance and scalability requirements. In most organizations, however, the use of computing services and networks is rapidly increasing. To be safe, you should design your application to perform well with and accommodate a larger number of directory entries than are currently stored in your directory service. By considering performance and scalability of the directory-related aspects of your application up front, you may avoid a costly redesign later.

When you're designing your application, avoid architectural choices that limit performance, require you to open many connections to the directory service, or make it difficult to use performance-enhancing techniques such as caching. If your application uses LDAP heavily, you may want to implement a shared pool of connections to the directory service. Figure 21.12 shows an example of a connection pool architecture.

Figure 21.12. An LDAP Connection Pool Architecture

A shared pool of connections offers several advantages:

  • The pool provides a central place for caching search, bind, and compare operations and for sharing results among threads within your application.

  • You can easily arrange to share one connection among several application threads, thereby reducing the number of simultaneous connections your application needs to make to the directory service.

  • The code to support robust features (such as automatic failover to an alternate server) can be implemented in one place in the connection pool.

Although your application may not require a complex structure that includes a shared connection pool, do consider what kind of architecture will help your application use the directory service efficiently and perform well.

Tip

One danger in using any abstraction layer (including the LDAP connection pool just described) is that you typically sacrifice some fidelity and lose the ability to take full advantage of all the LDAP features provided by the underlying LDAP SDK. For example, suppose you implement a connection pool that does not allow you to use arbitrary LDAPv3 controls. If later you found that your application would work better if it used an LDAPv3 extension that requires you to send a control to the server (such as a server-side sorting control), you would need to redesign your abstraction layer. Plan ahead, and use abstraction layers only when there is a clear advantage in doing so.


All LDAP applications perform better if they avoid issuing extraneous operations and if they use simple operations as much as possible. By minimizing your application's impact on CPU, disk, memory, and other directory server resources, you improve the performance of all applications. Here are some simple guidelines to follow:

  • When searching and reading entries, ask for only the attributes you need. Do not retrieve all attributes from every entry.

  • When modifying an entry, compare the new values with the ones already present in the entry and avoid sending unnecessary modify requests to the directory server.

  • Include useful information such as an (objectClass=person) component in search filters in order to reduce the number of entries the server will need to examine to return the entries requested .

  • Use efficient search filters whenever possible. For example, use an exact filter first, and then try a substring filter only if no entries are returned.

  • Avoid building assumptions into your application about the total number of entries or the shape of the directory tree (for example, flat or deep).

  • Think carefully before you create an application that relies on being able to find all the entries in the directory at once. This may not be feasible .

  • If you expect a lot of entries to be returned from a search operation, take advantage of the LDAPv3 Virtual List View (VLV) control to build a scalable user interface that processes the entries in manageable chunks . Refer to Chapter 3, LDAPv3 Extensions, for more information about the VLV control.

  • If your application includes a user interface for selecting directory entries, make sure it supports a search-based interface instead of (or in addition to) a list-based interface. A search-based interface will help your application handle thousands of entries and scale up gracefully as the directory service itself scales up.

Developing a Prototype and Conducting a Pilot

One of the best ways to prove your design and try out alternatives is to develop a working prototype. The prototype need not be complete or have the prettiest interface. You can create a prototype using scripting tools or other rapid application development (RAD) techniques, even if you plan to use different development tools to build the final application. However, your prototype should work and interact with other systems (including the directory service) in the same way you expect the final version of your application to do so.

As soon as a working prototype exists, conduct a pilot test to solicit feedback and learn about problems that must be fixed before you put the application into production service. Test your application's features, measure its performance, and solicit feedback from beta testers. Capture log files and other performance information and use them to conduct scaling tests. Use the data from these tests to estimate the load your application will place on the production directory service.

Use all the data obtained during the pilot to improve your application, including how it interacts with end users, with the directory service, and with other applications. After your application is deployed, substantial changes to it may dictate that you conduct another pilot. It is always better to find problems in pilot mode rather than in production mode.

Leveraging Existing Code

In many cases source code is available that can assist in developing your own applications. Most SDKs come with sample code, and vendors such as Netscape, Novell, Sun, and Microsoft make additional sample code available informally in newsgroups, in developer newsletters, and on developer CD-ROMs. The Internet at large is a great resource for locating complete directory-enabled applications; applications with freely available source code include LDAP-enabled message transfer agents (MTAs), several HTTP-to-LDAP gateways, LDAP modules for popular servers such as Apache, and LDAP-enabled e-mail clients . One good place to search for LDAP projects is http:// sourceforge .net.

You may want to create a Web site to publish LDAP-related source code within your own organization or publicly on the Internet on a site such as http://sourceforge.net so that the code can be reused by other people. Code modules explicitly designed to be reusable should be distributed in binary form as shared libraries or Java class files. Over time, try to build a large collection of code to serve as the starting point for new applications. You should, of course, ensure that any code promoted for reuse is of good quality and demonstrates appropriate use of the directory service.

Avoiding Common Mistakes

As when writing applications for any service that provides a lot of flexibility and functionality, the process of writing LDAP applications has some pitfalls. Many newcomers to LDAP application development make the same mistakes as those who came before them. Here are some common mistakes you should avoid:

  • Allowing abusive searches to get through to the directory service . A search that consumes a lot of resources on a directory server is an abusive search . Abusive searches include unindexed searches, searches that return a huge number of entries, and searches that read more information than is needed for the task at hand. If your application provides an interface with which end users interact to create LDAP search filters, implement simple checks to avoid abuse of the server. The kinds of searches that are abusive vary from one directory server implementation to another.

    For example, with Netscape Directory Server it is important to avoid substring filters that use fewer than three characters (for example, cn=*hi* ). You should also ensure that at least one ANDed component of each search filter references an indexed attribute type. Unindexed searches processed by Netscape Directory Server are flagged with notes=U in the server access log. You can also examine the access log for searches whose elapsed time ( etime ) is longer than a few seconds.

  • Not taking advantage of LDAP client-side size and time limits . To prevent searches from taking too long and monopolizing the directory service, use reasonable size and time limits in your application. Using these limits also protects your application and your users from being frustrated by a slow, unresponsive service.

  • Treating multiple values stored in one attribute as an ordered list . In LDAP, the attribute values associated with each attribute type are treated as an unordered set of values. Although many directory servers return the values for a given attribute in the same order they're stored, it is dangerous for an application to rely on this behavior. If you need a way to distinguish between two or more values for the same attribute, include something in the values themselves (such as a sequence number or other identifying text) to allow your application to tell the values apart.

  • Storing extremely large entries in the directory service . Most directory server and SDK implementations are designed with relatively small entries in mind. There is no hard-and-fast rule for how big is too big, but it is unusual for an entry to be larger than 100K.

  • Improperly handling zero-length passwords . If your application uses LDAP simple bind operations to test for valid passwords, make sure you check for zero-length or NULL passwords before passing them on to the directory server. LDAP servers return success responses for simple bind operations that contain a zero-length password and a syntactically valid DN, even though the server does not grant the privileges associated with the bind DN to the connection. In other words, LDAP simple bind operations with zero-length passwords always appear to the application to succeed when, in fact, no credentials were checked and no privileges were granted.

  • Improperly supporting LDAP referrals . The most common mistake users of the LDAP C API make with respect to referral support is forgetting to install a rebind function when automatic referral chasing is enabled. A rebind function is a callback function that is invoked by the SDK library to obtain credentials to use when connecting to another server. Without a rebind function in place, all referred connections are anonymous, causing errors or confusion when the directory is being modified or attributes protected by access control are being accessed.

    Another common referral-related mistake is not providing a way to disable automatic chasing of referrals. The ability to disable referrals is useful when you're troubleshooting directory problems or trying to improve performance in the face of unreachable servers.

  • Reading an entry immediately after it was modified and expecting to see recent changes . A short delay before changes made on a writable directory server are visible on a read-only replica is common. See Chapter 11, Replication Design, for a discussion of the loosely consistent replication strategy employed by most directory products. If your application is connected to a read-only directory replica, searches sometimes return stale data. Try to design your application so that it doesn't need to immediately read information that it just changed and, if appropriate, so that it warns users to expect a short delay before directory changes are visible. If it is essential for your application to immediately see the changes it makes, design it so that it can locate a writable directory server. The writable server can then be used to process reads as well as writes once a change has been made by your application (of course, requiring use of a writable server for reads diminishes the value of replication somewhat). Using a client-side "write-through" cache to hide replication propagation delay is also an option, but if the contents of the cache are flushed (when a user quits and reloads your application, for example), old directory data may reappear and confuse the user.

   


Understanding and Deploying LDAP Directory Services
Understanding and Deploying LDAP Directory Services (2nd Edition)
ISBN: 0672323168
EAN: 2147483647
Year: 2002
Pages: 242

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net