Network Deployment (Distributed operating systems), v8.0 > Secure applications and their environment > Authenticate users > Select a registry or repository > Standalone LDAP registries


Security failover among multiple LDAP servers

WAS security can be configured to attempt failovers between multiple Lightweight Directory Access Protocol (LDAP) hosts.

New feature: Beginning in WAS v8.0 you can configure the server to use the High Performance Extensible Logging (HPEL) log and trace infrastructure instead of using SystemOut.log , SystemErr.log, trace.log, and activity.log files or native z/OS logging facilities. If you are using HPEL, you can access all of your log and trace information using the LogViewer command-line tool from your server profile bin directory. See the information about using HPEL to troubleshoot applications for more information on using HPEL.New feature:

If the current active LDAP server is unavailable, WAS security attempts a failover to the first available LDAP host in the specified host list. The multiple LDAP servers can be replicas of the same master LDAP server, or they can be any LDAP host with the same schema, which contain data that is imported from the same LDAP Data Interchange Format (LDIF) file.

Whenever a failover occurs, WAS security always uses the first available LDAP server in the specified host list. For example, if there are four LDAP servers configured in the order of L1, L2, L3, and L4, L1 is treated as the primary LDAP server. The preference of connection is from L1 to L4. If, for example, WAS security is currently connected to L4, and failover or reconnection is necessary, WAS security first attempts to connect to L1, L2, and then L3 in that order until the connection is successful.

The current LDAP host name is logged in message CWSCJ0419I in the WAS log file, SystemOut.log. To reconnect to the primary LDAP host, run the WAS MBean method, resetLDAPBindInfo, with null,null as the input.

To configure LDAP failover among multiple LDAP hosts, use wsadmin or ConfigService to include the backup LDAP host, which does not have a number limitation. The LDAP host that is displayed in the admin console is the primary LDAP host, and is the first item listed in the LDAP host list in security.xml.

The WAS security realm name defaults to the primary LDAP host name that is displayed in the admin console. It includes a trailing colon and a port number (if one exists). However, the custom property, com.ibm.websphere.security.ldap.logicRealm, can be added to override the default security realm name. Use the logicRealm name to configure each cell to have its own LDAP host for interoperability and backward compatibility, and to provide flexibility for adding or removing the LDAP host dynamically. If migrating from a previous installation, the new logicRealm name does not take effect until administrative security is enabled again.

To be compatible with a previous release that does not support logic realm, the logicRealm name has to be the same as that used by the previous installation (the LDAP host name, including a trailing colon and port number).

When LDAP failover is configured by associating a single hostname to multiple IP addresses through the use of a load balancer (which does that translation transparently to WAS), entering an invalid password can cause multiple LDAP bind retries. WAS retries and the load balancer routes requests to multiple replicas. With the default settings, the number of LDAP bind retries is equal to one more than the number of associated IP addresses. This means a single invalid login attempt can cause the LDAP account to be locked. If the com.ibm.websphere.security.ldap.retryBind custom property is set to false, LDAP bind calls are not retried.

The following Jacl example shows how to use wsadmin to add a backup LDAP host for failover:

#---------------------------------------------------------------
# Main
#  This is a bi-modal script: it can be included in the wsadmin #  command invocation like this:
#     wsadmin -f LDAPAdd.jacl ldaphost 800
#
#  or the script can be sourced from the wsadmin command line:
#     wsadmin> source LDAPAdd.jacl
#     wsadmin> LDAPAdd ldaphost 800
#
#  The script expects some parameters:
#      arg1 - LDAP Server host name #      arg2 - LDAP Server port number
#---------------------------------------------------------------
if { !($argc == 2)} {
   puts ""
   puts "LDAPAdd: This script requires 2 parameters: LDAP server host name and LDAP server port number"
   puts "For example: LDAPAdd ldaphost 389"
   puts ""
   return;
}
else {
   set ldapServer        [lindex $argv 0]
   set ldapPort          [lindex $argv 1]
   LDAPAdd $ldapServer $ldapPort
   return;
}
proc LDAPAdd {ldapServer ldapPort args} {
   global AdminConfig AdminControl ldapServer ldapPort
   set ldapServer  lindex $args 0
   set ldapPort  lindex $args 1
   global ldapUserRegistryId
   # Get the LDAP user registry object from the security configuration    if { catch {$AdminConfig list LDAPUserRegistry} result } {
      puts stdout "\$AdminConfig list LDAPUserRegistry caught an exception $result\n"
      return
   }
   else {
      if {$result != {}} {
         set ldapUserRegistryId  lindex $result 0
      }
      else {
         puts stdout "\$AdminConfig list LDAPUserRegistry caught an exception $result\n"
         return;
      }

   # Set the host and port values in Attrs2
   set Attrs2  list  list hosts  list  list  list host    $ldapServer
   list port $ldapPort

   # Modify the LDAP configuration host object    $AdminConfig modify $ldapUserRegistryId $Attrs2
   $AdminConfig save }

The following Jython example shows how to use wsadmin to add a backup LDAP host for failover:

#---------------------------------------------------------------
# Add ldap hostname and port #     wsadmin -f LDAPAdd.py arg1 arg2
#
#  The script expects some parameters:
#      arg1 - LDAP Server hostname
#      arg2 - LDAP Server portnumber
#---------------------------------------------------------------
import java

#-------------------------------------------------------
# get the line separator and use to do the parsing
# since the line separator on different platform are different lineSeparator = java.lang.System.getProperty('line.separator')

#-------------------------------------------------------------------------------
# add LDAP host #-------------------------------------------------------------------------------
def LDAPAdd (ldapServer, ldapPort):
    global AdminConfig, lineSeparator, ldapUserRegistryId
    try:
        ldapObject = AdminConfig.list("LDAPUserRegistry")
        if len(ldapObject) == 0:
            print "LDAPUserRegistry ConfigId was not found\n"
            return

        ldapUserRegistryId = ldapObject.split(lineSeparator)[0]
        print "Got LDAPUserRegistry ConfigId is " + ldapUserRegistryId + "\n"
    except:
        print "AdminConfig.list('LDAPUserRegistry') caught an exception\n"

    try:
        secMbeans = AdminControl.queryNames('WebSphere:type=SecurityAdmin,*')
        if len(secMbeans) == 0:
            print "Security Mbean was not found\n"
            return

        secMbean = secMbeans.split(lineSeparator)[0]
        print "Got Security Mbean is " + secMbean + "\n"
    except:
        print "AdminControl.queryNames('WebSphere:type=SecurityAdmin,*') caught an exception\n"


    attrs2 = [["hosts", [[["host", ldapServer], ["port", ldapPort]]]]]
    try:
        AdminConfig.modify(ldapUserRegistryId, attrs2)
        try:
            AdminConfig.save()
            print "Done setting up attributes values for LDAP User Registry"
            print "Updated was saved successfully\n"
        except:
            print "AdminConfig.save() caught an exception\n"
    except:
        print "AdminConfig.modify(" + ldapUserRegistryId + ", " + attrs2 + ") caught an exception\n"
    return

#-------------------------------------------------------------------------------
# Main entry point
#-------------------------------------------------------------------------------
if len(sys.argv)
< 2 or len(sys.argv) > 3:
        print("LDAPAdd: this script requires 2 parameters: LDAP server hostname and LDAP server port number\n")
        print("e.g.: LDAPAdd ldaphost 389\n")
        sys.exit(1)
else:
        ldapServer = sys.argv[0]
        ldapPort = sys.argv[1]
        LDAPAdd(ldapServer, ldapPort)
        sys.exit(0)

Standalone LDAP registries
Update LDAP binding information

+

Search Tips   |   Advanced Search