BEA Logo BEA WebLogic Server Release 5.0

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

WebLogic LDAP realm

These are the release notes for the LDAP realm included with releases of WebLogic Server after version 5.1.0, service pack 7. WebLogic has rewritten the LDAP realm to provide vastly improved performance and configurability. It is highly recommended to upgrade your installation to a current Service Pack in order to take advantage of this functionality. If you are using an installation with Service Pack 0-6, please see our original documentation on the LDAP realm that was provided with those releases.

Because of the many changes introduced in the LDAP realm during its rewrite, the original v5.1.0 LDAP realm documentation does not apply to this release. Please consult these release notes for all information pertaining to the LDAP realm.

An introduction to the LDAP realm

Many large companies and organizations use the Lightweight Directory Access Protocol (LDAP) to store information about their employees, customers, and partners. The WebLogic LDAP realm allows WebLogic Server, and the applications it hosts, to use LDAP services to authenticate users, and to determine whether users can access certain services.

The WebLogic LDAP realm has been tested against the following LDAP servers:

  • OpenLDAP
  • iPlanet Directory Server
  • Microsoft Site Server

Although we cannot commit to supporting LDAP servers we have not tested against, we believe that our LDAP realm implementation is flexible enough that it should work against almost any LDAP server that uses a "reasonably sensible" schema.

Limitations of the LDAP realm

Presently, there is no standardized schema for storing access control information in LDAP directories. As a result, if you use the LDAP realm, you must continue to store access control lists in your server's weblogic.properties file. These access control lists may freely refer to users and groups defined in the LDAP server.

Since WebLogic Server reads the weblogic.properties file only once, at startup time, you will need to restart your server if you change the contents of any ACLs you define.

The LDAP realm currently supports only password-based authentication of users. Other mechanisms, such as S/KEY, may be supported in a future release.

In order to provide the best possible performance and stability, this version of the LDAP realm does not support a number of methods on the Java classes it uses. These methods, if invoked on WebLogic servers that talked to large LDAP directories, could cause effects similar to denial-of-service (DoS) attacks. For more specific information, see below.

Installation and configuration

To direct WebLogic Server to use the LDAP realm, you must add the following to your weblogic.properties file:

weblogic.security.realmClass=\
      weblogic.security.ldaprealm.LDAPRealm
    

In addition, the LDAP realm relies upon another file, called ldaprealm.properties, for its own configuration information. (The realm cannot retrieve this information directly from the weblogic.properties file due to the historical structuring of the server's internal configuration code.)

You will find an example copy of the ldaprealm.properties file in the classes/weblogic/security/ldaprealm directory. Make a copy of this file, and store it in your WebLogic home directory (the directory in which you start the server). There is also a sample provided with WebLogic 5.1.0 Service Pack 7 and higher.

Note: you must set up your ldaprealm.properties file to reflect the configuration of your LDAP server before you start WebLogic Server. The values that we provide in the copy of this file that we ship are examples only, and will not work without modification.

Organization of the properties file

The ldaprealm.properties file is organized as a typical Java-style properties file. Properties are named in name=value pairs, with leading and trailing white space discarded from both names and values. The "#" character is the comment character.

The example ldaprealm.properties file is divided into a number of distinct blocks. The first block you will see contains a server.alias property. This alias is simply a prefix that the realm uses to name other properties. For example, if you decide to set the server.alias property to gribbly, then the LDAP realm will look for all its properties under names such as gribbly.server.host. If you do not provide a value for this property, then the LDAP realm will simply look for properties with names like server.host.

This property aliasing capability is mostly of use if you find yourself needing to switch between several different LDAP servers. Otherwise, you can safely ignore it.

Each property in the ldaprealm.properties file is described below. Unless the description of a particular property refers to a default value, that property must be present and have a correct value in order for the LDAP realm to function correctly.

Connection properties

In order to connect to an LDAP server, you must tell the LDAP realm where your server is, and how to talk to it.

server.host
The hostname or IP address of the LDAP server you want to use.
server.ssl
Whether or not to use the Secure Socket Layer (SSL) protocol to talk to the LDAP server. This is false by default, for maximum compatibility, but you may want to set it to true if you are worried about your connection or passwords being snooped. (Do note, though, that turning on SSL will significantly slow down the connection to the LDAP server.)
server.port
The port number on which the LDAP server you want to use is listening for connections. You do not normally need to set this property, as it defaults to 636 (the standard LDAP-over-SSL port) if you have set the server.ssl property to true, and 389 (the standard plaintext SSL port) if you are not.

For the LDAP realm to be able to authenticate users, you must specify a user on the LDAP server to connect as. This user does not need to have any special privileges on the LDAP server, and we recommend that you use an unprivileged user.

server.principal
The distinguished name (DN) of the user you want to connect as. If you specify this property incorrectly, WebLogic Server will not start correctly.
server.credential
The password of the user you want to connect as. If you specify this property incorrectly, WebLogic Server will not start correctly.

User properties

When WebLogic Server needs to authenticate a user, or determine whether that user is allowed to perform some action, it must first find the user. It hands this task off to the LDAP realm, which searches the LDAP directory to find users. The following properties control the search process.

user.dn
This property tells the LDAP realm where in the LDAP directory it should start looking for users. You should specify this as a DN that identifies the root under which you store users that WebLogic should be able to see.
user.dn.n
If you store WebLogic users under multiple roots in your directory, you can specify these roots as user.dn.1, user.dn.2, and so on. The LDAP realm will search under each of these roots in turn until it finds a matching user.
user.scope
This specifies the scope with which the LDAP realm should search for users. There are three valid scopes: subtree, one-level, and base. Subtree scope indicates that the LDAP realm should search everything under the base DN. One-level scope tells the LDAP server to only search entries one level down from the base DN. We have yet to find a sensible use for base scope, but we include it here for completeness. By default, the LDAP realm always uses subtree scope for searches; you probably don't need to modify this.
user.scope.n
If necessary, you can specify multiple user search scopes. This will cause user.scope.1 to be used to search under user.dn.1, user.scope.2 under user.dn.2, and so on.
user.filter
This is the LDAP search filter that the realm will send to the server to find a user. The filter must contain at least one instance of the string %u; the LDAP realm will replace each %u in the filter with the name of the user it is searching for.
user.filter.n
If you want to use multiple different search filters to find users, you can name them user.filter.1 (which will be used with user.dn.1 and user.scope.1, if they exist), user.filter.2 (used with user.dn.2 and user.scope.2), and so on. These filters will be used in turn until one causes the LDAP server to return a match.

Note that you must supply at least one value for each of user.dn and user.filter. If you supply multiple values, those values will be used together. Consider the following fragment:

server.alias=example
example.user.dn.1 = ou=people, dc=asia, dc=example, dc=com
example.user.dn.2 = ou=people, dc=europe, dc=example, dc=com
example.user.filter = (&(uid=%u)(objectclass=person))
    

In this case, the single search filter we specified will be used to search each of the root DNs. This is useful if the various branches of the directory all use the same schema. However, we can also use a different search filter for each root DN we want to search:

# no server.alias property set here
user.dn.1 = ou=sales, ou=recent-acquisition, o=test.net
user.filter.1 = (&(mail=%u@*)(objectclass=unperson))
user.dn.2 = ou=marketing, ou=employees, o=test.net
user.filter.2 = (&(uid=%u)(objectclass=person))
    

Here, the first filter will be used with the first DN when searching, the second filter with the second DN, and so on.

Group properties

To determine whether some user may perform a particular action, WebLogic Server may need to determine whether that user is a member of some group. If the user and group in question don't exist in your weblogic.properties file, the group membership check will be performed by the LDAP realm.

Before the LDAP realm can check a group to see if it contains some user, it must first find that group. It finds groups in the same way as users; the properties in the ldaprealm.properties file that tell the LDAP realm how to find groups are prefixed with group instead of user. Hence group.dn in place of user.dn, and so on.

Group membership properties

The search that the LDAP realm uses deserves some explanation. The motivation for the way we do things is that we want groups to be able to contain other groups, as well as simply containing users. If group g1 contains group g2, and g2 contains user u, then we consider g1 as containing u. This makes the life of LDAP directory administrators nice and easy, but it makes more work for the LDAP realm, which must now perform the check for group membership "backwards".

To check whether a user or group is a member of another group, the LDAP realm must thus be told how to find all groups that contain that member. Once it has this information, it can perform the rest of the necessary work efficiently.

membership.filter
This property specifies the search filter to use for finding the groups that contain a given member. Any instances of %M in the filter are replaced with the full DN (not the name as WebLogic Server sees it) of the member to check for, and %G is replaced with the full DN of the group that is being checked.
membership.scope.depth
This property is specific to the LDAP schema used by Microsoft Site Server (MSS), and is not needed by most other LDAP servers. MSS stores references to the members of a group in entries one level under the entry for the group. (By contrast, most other LDAP servers store the DNs of group members as attributed of the group entry.) If you are using this kind of schema, you should set this property to the maximum depth below the group entry that member entries are held. In the case of MSS, this should be set to 1. For almost all other LDAP servers, you should not need to set this property at all.

Here is some concise pseudocode for the membership check algorithm:

check_membership(group g, principal p):
  for each group g1 that contains p directly:
    if g1 == g or check_membership(g, g1)
    then return success
  return failure
    

Optimizing performance

The key to yielding the best performance from the LDAP realm is to tune your LDAP server so that it can answer queries as quickly as possible. For most LDAP servers, this involves explicitly telling the LDAP server to index all of the attributes that you will use as search keys in your LDAP realm search filters.

Consider an LDAP server for which our LDAP realm's user search filter looks like this:

user.filter=(&(uid=%u)(objectclass=person))
    

This suggests that we should configure our LDAP server to maintain indexes that will let it perform fast equality searches over the uid and objectclass attributes.

If you specify any unindexed attributes as search keys, most LDAP servers will have to fall back to performing linear searches over those attributes. If you have a large number of entries with such attributes, the performance and scalability of anything that depends on your LDAP server will be greatly affected.

Also important to performance is the WebLogic Server's Caching Realm. Local cache lookups are tens of thousands of times faster than queries of the LDAP server. If you do not have caching turned on, you should read the Caching Realm documentation and spend a little time tuning it so that your WebLogic Server doesn't have to contact your LDAP server quite so frequently.

In addition to the Caching Realm, the LDAP realm uses an internal cache to speed up LDAP searches. This cache is enabled by default. The properties that control this cache are as follows:

cache.ttl
The time-to-live for entries in the cache, in seconds. By default, this is set to 60 seconds. If you want to disable this cache, set the value of this property to zero.
cache.size
The size of the cache, in kilobytes. By default, this is 32K. If you want to disable this cache, set the value of this property to zero.

To reduce the number of searches that the LDAP realm must perform when checking a principal to see if it is a member of a group, it may be best to keep your group hierarchies shallow. The number of searches that the LDAP realm must perform is roughly proportional to the depth of your group hierarchy. (By "group hierarchy", we mean groups that contain other groups. This is not related to the depth of your LDAP directory tree.)

Troubleshooting the LDAP realm

If you are experiencing problems with the LDAP realm, you can enable a debugging property to get a large amount of logging information about the workings of both the Caching Realm and the LDAP realm. This is a boolean property, named weblogic.security.cache.debug, and you can set it either in your weblogic.properties file, or on the Java command line when starting your server.

Note that this property generates a huge number of log messages, so you should not enable it in a deployment situation.

If you find that WebLogic Server takes some time to "notice" updates you make to your LDAP server, you should check the time-to-live values of the caches in the Caching Realm and the LDAP realm. You will want to strike a balance between WebLogic seeing updates in a timely manner and lowering the amount of traffic between WebLogic and your LDAP server.

Unsupported methods of Java classes

The following methods are not supported by this version of the WebLogic LDAP realm. For each method, we describe its behavior, along with our rationale for not supporting it.

weblogic.security.acl.ListableRealm.getUsers
Throws an exception. These methods are generally only used by the WebLogic Administration Console, and can cause either WebLogic Server or your LDAP server to hang for a long time, and perhaps run out of memory, if used on an LDAP server with large numbers of users or groups.
weblogic.security.acl.ListableRealm.getGroups
Works, but with caveats. These methods are generally only used by the WebLogic Administration Console, and can cause either WebLogic Server or your LDAP server to hang for a long time, and perhaps run out of memory, if used on an LDAP server with large numbers of users or groups. This implementation of the getGroups method can only yield approximate group names, doing best if the "%g" substrings in your group search filters are the only text on the right hand side of a match clause (good: "(cn=%g)", bad: "(cn=%g@blatz.com)").
java.security.acl.Group.addMember
java.security.acl.Group.removeMember
Always returns false. You must use your LDAP server's administrative tools to manage users and groups in the LDAP directory.
java.security.acl.Group.members
Always returns an empty enumeration. This m ethod does not scale to groups with large numbers of members (see above).

If you are writing an application that genuinely needs to use the information that any of the above methods would provide, we recommend that you make careful use of the Mozilla Directory SDK to obtain this information directly from your LDAP server. You should be aware that many LDAP servers will suffer severe problems if you attempt to perform searches or queries that return large results (particularly for entries with large numbers of attributes).

Useful tools and references

During the development and testing of the LDAP realm, we found a number of useful documents, services, and free software packages.

  • Argonne National Laboratory's LDAP Browser/Editor is an excellent Java-based tool, which we used heavily during the development of the WebLogic LDAP realm.
  • If you do not have a background with LDAP, Mark Wilcox's LDAP FAQ may be a useful starting point.
  • The WebLogic LDAP realm is implemented using the Mozilla Directory SDK.
  • We performed most of our scalability testing using the free OpenLDAP server and tools, obtaining excellent performance against a server populated with more than 500,000 users, with some groups exceeding 125,000 members.

Sample properties file


# This is an example configuration file for the LDAP security realm of
# WebLogic Server.  You must edit this file before you can use it.
#
# To set this file up, uncomment the "server.alias" line below that
# corresponds to the kind of LDAP server you are using, then scroll
# down and edit the properties that begin with that alias.
#
# For example, if you are using an OpenLDAP server, you should
# uncomment the line that reads "server.alias=openldap", and then edit
# the properties below that begin with the string "openldap".
#
# Below is a quick recap of the properties you may need to edit.  For
# full details, please see the LDAP realm documentation.
#
# server.host
#   the hostname of your LDAP server (no default value)
#
# server.port
#   the port number to connect to (defaults to 389 for plaintext
#   connections, and 636 for SSL connections)
#
# server.ssl
#   whether to use SSL to talk to the LDAP server (false by default,
#   but passwords may be sent in plaintext)
#
# server.principal
#   DN of the principal to connect as (no default; we recommend an
#   unprivileged user)
#
# server.credential
#   password of the principal to connect as (no default)
#
# user.dn, user.dn.1, user.dn.2, etc.
#   one or more base DNs to search for users (no default)
#
# user.filter, user.filter.1, user.filter.2, etc.
#   search filters for matching user entries, with the name of the
#   user to search for substituted for %u (no default)
#
# user.scope, user.scope.1, user.scope.2, etc.
#   scope for searching for users; can be "subtree", "one-level", or
#   "base" (defaults to subtree)
#
# group.dn, group.dn.1, group.dn.2, etc.
#   one or more base DNs to search for groups (no default)
#
# group.filter, group.filter.1, group.filter.2, etc.
#   search filters for matching group entries, with the name of the
#   group to search for substituted for %g (no default)
#
# group.scope, group.scope.1, group.scope.2, etc.
#   scope for searching for groups; can be "subtree", "one-level", or
#   "base" (defaults to subtree)
#
# membership.filter
#   search filters for matching members of groups, with %M substituted
#   for the DN of the member to search for, and %G for the DN of the
#   group to search (no default)
#
# membership.scope, membership.scope.1, membership.scope.2, etc.
#   scope for searching for group members; can be "subtree",
#   "one-level", or "base" (defaults to subtree)

########
######## The actual properties begin below.
########


### Server type

# server.alias=microsoft
# server.alias=netscape
# server.alias=openldap

### OpenLDAP

# The OpenLDAP server doesn't really have a default schema for users
# and groups.  The example schema we use here is similar to the one
# used by the Netscape Directory Server, but it uses DomainComponent,
# or dc, attributes for the root of the namespace.

openldap.server.host=ldapserver.example.com
openldap.server.principal=cn=Manager, dc=example, dc=com
openldap.server.credential=*secret*

openldap.user.dn=ou=people, dc=example, dc=com
openldap.user.filter=(&(uid=%u)(objectclass=person))

openldap.group.dn=ou=groups, dc=example, dc=com
openldap.group.filter=(&(cn=%g)(objectclass=groupofuniquenames))

openldap.membership.filter=(&(uniquemember=%M)(objectclass=groupofuniquenames))

### Microsoft Site Server

# This follows the default Microsoft Site Server (MSS) schema.

microsoft.server.host=ldapserver.example.com
microsoft.server.principal=cn=Administrator, ou=Members, o=ExampleMembershipDir
microsoft.server.credential=*secret*

microsoft.user.dn=ou=Members, o=ExampleMembershipDir
microsoft.user.filter=(&(cn=%u)(objectclass=member))

microsoft.group.dn=ou=Groups, o=ExampleMembershipDir
microsoft.group.filter=(&(cn=%g)(objectclass=mgroup))

# MSS uses an unusual schema to handle groups.  A group is an entry in
# the tree, and each member of the group is a separate entry (with an
# odd name) immediately under the group's node in the tree.  This
# forces the LDAP realm into some contortions when performing group
# membership checks.  Other LDAP servers store members as attributes
# of the group entry.

microsoft.membership.scope.depth=1
microsoft.membership.scope=sub
microsoft.membership.filter=(|(&(memberobject=%M)(objectclass=memberof))(&(groupobject=%M)(objectclass=groupmemberof)))

### Netscape Directory Server

# This follows the default schema that you get when you use the
# Netscape Directory Server administration console, in its default
# configuration, to manage users and groups.

netscape.server.host=ldapserver.example.com
netscape.server.principal=uid=admin, ou=Administrators, ou=TopologyManagement, o=NetscapeRoot
netscape.server.credential=*secret*

netscape.user.dn=ou=people, o=example.com
netscape.user.filter=(&(uid=%u)(objectclass=person))

netscape.group.dn=ou=groups, o=example.com
netscape.group.filter=(&(cn=%g)(objectclass=groupofuniquenames))

netscape.membership.filter=(&(uniquemember=%M)(objectclass=groupofuniquenames))



 

 

Copyright © 2000 BEA Systems, Inc. All rights reserved.
Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.
Last updated 12/24/2000