org.apache.catalina.realm

Class JNDIRealm

Implemented Interfaces:
Lifecycle, MBeanRegistration, Realm

public class JNDIRealm
extends RealmBase

Implementation of Realm that works with a directory server accessed via the Java Naming and Directory Interface (JNDI) APIs. The following constraints are imposed on the data structure in the underlying directory server:
  • The user may be authenticated by binding to the directory with the username and password presented. This method is used when the userPassword property is not specified.
  • The user may be authenticated by retrieving the value of an attribute from the directory and comparing it explicitly with the value presented by the user. This method is used when the userPassword property is specified, in which case:
  • Each group of users that has been assigned a particular role may be represented by an individual element in the top level DirContext that is accessed via the connectionURL property. This element has the following characteristics:
  • In addition, roles may be represented by the values of an attribute in the user's element whose name is configured by the userRoleName property.
  • Note that the standard <security-role-ref> element in the web application deployment descriptor allows applications to refer to roles programmatically by names other than those used in the directory server itself.
  • TODO - Support connection pooling (including message format objects) so that authenticate() does not have to be synchronized.

    WARNING - There is a reported bug against the Netscape provider code (com.netscape.jndi.ldap.LdapContextFactory) with respect to successfully authenticated a non-existing user. The report is here: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11210 . With luck, Netscape has updated their provider code and this is not an issue.

    Version:
    $Revision: 1.12.2.2 $ $Date: 2004/11/19 15:01:34 $

    Authors:
    John Holman
    Craig R. McClanahan

    Field Summary

    static String
    DEREF_ALIASES
    Constant that holds the name of the environment property for specifying the manner in which aliases should be dereferenced.
    protected String
    alternateURL
    An alternate URL, to which, we should connect if connectionURL fails.
    protected String
    authentication
    The type of authentication to use
    protected int
    connectionAttempt
    The number of connection attempts.
    protected String
    connectionName
    The connection username for the server we will contact.
    protected String
    connectionPassword
    The connection password for the server we will contact.
    protected String
    connectionURL
    The connection URL for the server we will contact.
    protected DirContext
    context
    The directory context linking us to our directory server.
    protected String
    contextFactory
    The JNDI context factory used to acquire our InitialContext.
    protected int
    curUserPattern
    The current user pattern to be used for lookup and binding of a user.
    protected String
    derefAliases
    How aliases should be dereferenced during search operations.
    protected static String
    info
    Descriptive information about this Realm implementation.
    protected static String
    name
    Descriptive information about this Realm implementation.
    protected String
    protocol
    The protocol that will be used in the communication with the directory server.
    protected String
    referrals
    How should we handle referrals? Microsoft Active Directory can't handle the default case, so an application authenticating against AD must set referrals to "follow".
    protected String
    roleBase
    The base element for role searches.
    protected MessageFormat
    roleFormat
    The MessageFormat object associated with the current roleSearch.
    protected String
    roleName
    The name of the attribute containing roles held elsewhere
    protected String
    roleSearch
    The message format used to select roles for a user, with "{0}" marking the spot where the distinguished name of the user goes.
    protected boolean
    roleSubtree
    Should we search the entire subtree for matching memberships?
    protected String
    userBase
    The base element for user searches.
    protected String
    userPassword
    The attribute name used to retrieve the user password.
    protected String
    userPattern
    The message format used to form the distinguished name of a user, with "{0}" marking the spot where the specified username goes.
    protected String[]
    userPatternArray
    A string of LDAP user patterns or paths, ":"-separated These will be used to form the distinguished name of a user, with "{0}" marking the spot where the specified username goes.
    protected MessageFormat[]
    userPatternFormatArray
    An array of MessageFormat objects associated with the current userPatternArray.
    protected String
    userRoleName
    The name of an attribute in the user's entry containing roles for that user
    protected String
    userSearch
    The message format used to search for a user, with "{0}" marking the spot where the username goes.
    protected MessageFormat
    userSearchFormat
    The MessageFormat object associated with the current userSearch.
    protected boolean
    userSubtree
    Should we search the entire subtree for matching users?

    Fields inherited from class org.apache.catalina.realm.RealmBase

    container, controller, debug, digest, digestEncoding, domain, host, info, initialized, lifecycle, md, md5Encoder, md5Helper, mserver, oname, path, sm, started, support, type, validate

    Fields inherited from interface org.apache.catalina.Lifecycle

    AFTER_START_EVENT, AFTER_STOP_EVENT, BEFORE_START_EVENT, BEFORE_STOP_EVENT, START_EVENT, STOP_EVENT

    Method Summary

    Principal
    authenticate(DirContext context, String username, String credentials)
    Return the Principal associated with the specified username and credentials, if there is one; otherwise return null.
    Principal
    authenticate(String username, String credentials)
    Return the Principal associated with the specified username and credentials, if there is one; otherwise return null.
    protected boolean
    bindAsUser(DirContext context, org.apache.catalina.realm.User user, String credentials)
    Check credentials by binding to the directory as the user
    protected boolean
    checkCredentials(DirContext context, org.apache.catalina.realm.User user, String credentials)
    Check whether the given User can be authenticated with the given credentials.
    protected void
    close(DirContext context)
    Close any open connection to the directory server for this Realm.
    protected boolean
    compareCredentials(DirContext context, org.apache.catalina.realm.User info, String credentials)
    Check whether the credentials presented by the user match those retrieved from the directory.
    protected String
    doRFC2254Encoding(String inString)
    Given an LDAP search string, returns the string with certain characters escaped according to RFC 2254 guidelines.
    String
    getAlternateURL()
    Getter for property alternateURL.
    String
    getAuthentication()
    Return the type of authentication to use.
    String
    getConnectionName()
    Return the connection username for this Realm.
    String
    getConnectionPassword()
    Return the connection password for this Realm.
    String
    getConnectionURL()
    Return the connection URL for this Realm.
    String
    getContextFactory()
    Return the JNDI context factory for this Realm.
    java.lang.String
    getDerefAliases()
    Return the derefAliases setting to be used.
    protected Hashtable
    getDirectoryContextEnvironment()
    Create our directory context configuration.
    protected String
    getName()
    Return a short name for this Realm implementation.
    protected String
    getPassword(String username)
    Return the password associated with the given principal's user name.
    protected Principal
    getPrincipal(String username)
    Return the Principal associated with the given user name.
    String
    getProtocol()
    Return the protocol to be used.
    String
    getReferrals()
    Returns the current settings for handling JNDI referrals.
    String
    getRoleBase()
    Return the base element for role searches.
    String
    getRoleName()
    Return the role name attribute name for this Realm.
    String
    getRoleSearch()
    Return the message format pattern for selecting roles in this Realm.
    boolean
    getRoleSubtree()
    Return the "search subtree for roles" flag.
    protected List
    getRoles(DirContext context, org.apache.catalina.realm.User user)
    Return a List of roles associated with the given User.
    protected org.apache.catalina.realm.User
    getUser(DirContext context, String username)
    Return a User object containing information about the user with the specified username, if found in the directory; otherwise return null.
    String
    getUserBase()
    Return the base element for user searches.
    protected org.apache.catalina.realm.User
    getUserByPattern(DirContext context, String username, String[] attrIds)
    Use the UserPattern configuration attribute to locate the directory entry for the user with the specified username and return a User object; otherwise return null.
    protected org.apache.catalina.realm.User
    getUserBySearch(DirContext context, String username, String[] attrIds)
    Search the directory to return a User object containing information about the user with the specified username, if found in the directory; otherwise return null.
    String
    getUserPassword()
    Return the password attribute used to retrieve the user password.
    String
    getUserPattern()
    Return the message format pattern for selecting users in this Realm.
    String
    getUserRoleName()
    Return the user role name attribute name for this Realm.
    String
    getUserSearch()
    Return the message format pattern for selecting users in this Realm.
    boolean
    getUserSubtree()
    Return the "search subtree for users" flag.
    protected DirContext
    open()
    Open (if necessary) and return a connection to the configured directory server for this Realm.
    protected String[]
    parseUserPatternString(String userPatternString)
    Given a string containing LDAP patterns for user locations (separated by parentheses in a pseudo-LDAP search string format - "(location1)(location2)", returns an array of those paths.
    protected void
    release(DirContext context)
    Release our use of this connection so that it can be recycled.
    void
    setAlternateURL(String alternateURL)
    Setter for property alternateURL.
    void
    setAuthentication(String authentication)
    Set the type of authentication to use.
    void
    setConnectionName(String connectionName)
    Set the connection username for this Realm.
    void
    setConnectionPassword(String connectionPassword)
    Set the connection password for this Realm.
    void
    setConnectionURL(String connectionURL)
    Set the connection URL for this Realm.
    void
    setContextFactory(String contextFactory)
    Set the JNDI context factory for this Realm.
    void
    setDerefAliases(java.lang.String derefAliases)
    Set the value for derefAliases to be used when searching the directory.
    void
    setProtocol(String protocol)
    Set the protocol for this Realm.
    void
    setReferrals(String referrals)
    How do we handle JNDI referrals? ignore, follow, or throw (see javax.naming.Context.REFERRAL for more information).
    void
    setRoleBase(String roleBase)
    Set the base element for role searches.
    void
    setRoleName(String roleName)
    Set the role name attribute name for this Realm.
    void
    setRoleSearch(String roleSearch)
    Set the message format pattern for selecting roles in this Realm.
    void
    setRoleSubtree(boolean roleSubtree)
    Set the "search subtree for roles" flag.
    void
    setUserBase(String userBase)
    Set the base element for user searches.
    void
    setUserPassword(String userPassword)
    Set the password attribute used to retrieve the user password.
    void
    setUserPattern(String userPattern)
    Set the message format pattern for selecting users in this Realm.
    void
    setUserRoleName(String userRoleName)
    Set the user role name attribute name for this Realm.
    void
    setUserSearch(String userSearch)
    Set the message format pattern for selecting users in this Realm.
    void
    setUserSubtree(boolean userSubtree)
    Set the "search subtree for users" flag.
    void
    start()
    Prepare for active use of the public methods of this Component.
    void
    stop()
    Gracefully shut down active use of the public methods of this Component.

    Methods inherited from class org.apache.catalina.realm.RealmBase

    Digest, addLifecycleListener, addPropertyChangeListener, authenticate, authenticate, authenticate, authenticate, destroy, digest, findLifecycleListeners, findSecurityConstraints, getContainer, getController, getDebug, getDigest, getDigest, getDigestEncoding, getDomain, getInfo, getName, getObjectName, getPassword, getPrincipal, getType, getValidate, hasMessageDigest, hasResourcePermission, hasRole, hasUserDataPermission, init, log, log, main, postDeregister, postRegister, preDeregister, preRegister, removeLifecycleListener, removePropertyChangeListener, setContainer, setController, setDebug, setDigest, setDigestEncoding, setValidate, start, stop

    Field Details

    DEREF_ALIASES

    public static final String DEREF_ALIASES
    Constant that holds the name of the environment property for specifying the manner in which aliases should be dereferenced.


    alternateURL

    protected String alternateURL
    An alternate URL, to which, we should connect if connectionURL fails.


    authentication

    protected String authentication
    The type of authentication to use


    connectionAttempt

    protected int connectionAttempt
    The number of connection attempts. If greater than zero we use the alternate url.


    connectionName

    protected String connectionName
    The connection username for the server we will contact.


    connectionPassword

    protected String connectionPassword
    The connection password for the server we will contact.


    connectionURL

    protected String connectionURL
    The connection URL for the server we will contact.


    context

    protected DirContext context
    The directory context linking us to our directory server.


    contextFactory

    protected String contextFactory
    The JNDI context factory used to acquire our InitialContext. By default, assumes use of an LDAP server using the standard JNDI LDAP provider.


    curUserPattern

    protected int curUserPattern
    The current user pattern to be used for lookup and binding of a user.


    derefAliases

    protected String derefAliases
    How aliases should be dereferenced during search operations.


    info

    protected static final String info
    Descriptive information about this Realm implementation.


    name

    protected static final String name
    Descriptive information about this Realm implementation.


    protocol

    protected String protocol
    The protocol that will be used in the communication with the directory server.


    referrals

    protected String referrals
    How should we handle referrals? Microsoft Active Directory can't handle the default case, so an application authenticating against AD must set referrals to "follow".


    roleBase

    protected String roleBase
    The base element for role searches.


    roleFormat

    protected MessageFormat roleFormat
    The MessageFormat object associated with the current roleSearch.


    roleName

    protected String roleName
    The name of the attribute containing roles held elsewhere


    roleSearch

    protected String roleSearch
    The message format used to select roles for a user, with "{0}" marking the spot where the distinguished name of the user goes.


    roleSubtree

    protected boolean roleSubtree
    Should we search the entire subtree for matching memberships?


    userBase

    protected String userBase
    The base element for user searches.


    userPassword

    protected String userPassword
    The attribute name used to retrieve the user password.


    userPattern

    protected String userPattern
    The message format used to form the distinguished name of a user, with "{0}" marking the spot where the specified username goes.


    userPatternArray

    protected String[] userPatternArray
    A string of LDAP user patterns or paths, ":"-separated These will be used to form the distinguished name of a user, with "{0}" marking the spot where the specified username goes. This is similar to userPattern, but allows for multiple searches for a user.


    userPatternFormatArray

    protected MessageFormat[] userPatternFormatArray
    An array of MessageFormat objects associated with the current userPatternArray.


    userRoleName

    protected String userRoleName
    The name of an attribute in the user's entry containing roles for that user


    userSearch

    protected String userSearch
    The message format used to search for a user, with "{0}" marking the spot where the username goes.


    userSearchFormat

    protected MessageFormat userSearchFormat
    The MessageFormat object associated with the current userSearch.


    userSubtree

    protected boolean userSubtree
    Should we search the entire subtree for matching users?

    Method Details

    authenticate

    public Principal authenticate(DirContext context,
                                  String username,
                                  String credentials)
                throws NamingException
    Return the Principal associated with the specified username and credentials, if there is one; otherwise return null.

    Parameters:
    context - The directory context
    username - Username of the Principal to look up
    credentials - Password or other credentials to use in authenticating this username


    authenticate

    public Principal authenticate(String username,
                                  String credentials)
    Return the Principal associated with the specified username and credentials, if there is one; otherwise return null. If there are any errors with the JDBC connection, executing the query or anything we return null (don't authenticate). This event is also logged, and the connection will be closed so that a subsequent request will automatically re-open it.
    Specified by:
    authenticate in interface Realm
    Overrides:
    authenticate in interface RealmBase

    Parameters:
    username - Username of the Principal to look up
    credentials - Password or other credentials to use in authenticating this username


    bindAsUser

    protected boolean bindAsUser(DirContext context,
                                 org.apache.catalina.realm.User user,
                                 String credentials)
                throws NamingException
    Check credentials by binding to the directory as the user

    Parameters:
    context - The directory context
    user - The User to be authenticated
    credentials - Authentication credentials


    checkCredentials

    protected boolean checkCredentials(DirContext context,
                                       org.apache.catalina.realm.User user,
                                       String credentials)
                throws NamingException
    Check whether the given User can be authenticated with the given credentials. If the userPassword configuration attribute is specified, the credentials previously retrieved from the directory are compared explicitly with those presented by the user. Otherwise the presented credentials are checked by binding to the directory as the user.

    Parameters:
    context - The directory context
    user - The User to be authenticated
    credentials - The credentials presented by the user


    close

    protected void close(DirContext context)
    Close any open connection to the directory server for this Realm.

    Parameters:
    context - The directory context to be closed


    compareCredentials

    protected boolean compareCredentials(DirContext context,
                                         org.apache.catalina.realm.User info,
                                         String credentials)
                throws NamingException
    Check whether the credentials presented by the user match those retrieved from the directory.

    Parameters:
    context - The directory context
    info - The User to be authenticated
    credentials - Authentication credentials


    doRFC2254Encoding

    protected String doRFC2254Encoding(String inString)
    Given an LDAP search string, returns the string with certain characters escaped according to RFC 2254 guidelines. The character mapping is as follows: char -> Replacement --------------------------- * -> \2a ( -> \28 ) -> \29 \ -> \5c \0 -> \00

    Parameters:
    inString - string to escape according to RFC 2254 guidelines

    Returns:
    String the escaped/encoded result


    getAlternateURL

    public String getAlternateURL()
    Getter for property alternateURL.

    Returns:
    Value of property alternateURL.


    getAuthentication

    public String getAuthentication()
    Return the type of authentication to use.


    getConnectionName

    public String getConnectionName()
    Return the connection username for this Realm.


    getConnectionPassword

    public String getConnectionPassword()
    Return the connection password for this Realm.


    getConnectionURL

    public String getConnectionURL()
    Return the connection URL for this Realm.


    getContextFactory

    public String getContextFactory()
    Return the JNDI context factory for this Realm.


    getDerefAliases

    public java.lang.String getDerefAliases()
    Return the derefAliases setting to be used.


    getDirectoryContextEnvironment

    protected Hashtable getDirectoryContextEnvironment()
    Create our directory context configuration.

    Returns:
    java.util.Hashtable the configuration for the directory context.


    getName

    protected String getName()
    Return a short name for this Realm implementation.
    Overrides:
    getName in interface RealmBase


    getPassword

    protected String getPassword(String username)
    Return the password associated with the given principal's user name.
    Overrides:
    getPassword in interface RealmBase


    getPrincipal

    protected Principal getPrincipal(String username)
    Return the Principal associated with the given user name.
    Overrides:
    getPrincipal in interface RealmBase


    getProtocol

    public String getProtocol()
    Return the protocol to be used.


    getReferrals

    public String getReferrals()
    Returns the current settings for handling JNDI referrals.


    getRoleBase

    public String getRoleBase()
    Return the base element for role searches.


    getRoleName

    public String getRoleName()
    Return the role name attribute name for this Realm.


    getRoleSearch

    public String getRoleSearch()
    Return the message format pattern for selecting roles in this Realm.


    getRoleSubtree

    public boolean getRoleSubtree()
    Return the "search subtree for roles" flag.


    getRoles

    protected List getRoles(DirContext context,
                            org.apache.catalina.realm.User user)
                throws NamingException
    Return a List of roles associated with the given User. Any roles present in the user's directory entry are supplemented by a directory search. If no roles are associated with this user, a zero-length List is returned.

    Parameters:
    context - The directory context we are searching
    user - The User to be checked


    getUser

    protected org.apache.catalina.realm.User getUser(DirContext context,
                                                     String username)
                throws NamingException
    Return a User object containing information about the user with the specified username, if found in the directory; otherwise return null. If the userPassword configuration attribute is specified, the value of that attribute is retrieved from the user's directory entry. If the userRoleName configuration attribute is specified, all values of that attribute are retrieved from the directory entry.

    Parameters:
    context - The directory context
    username - Username to be looked up


    getUserBase

    public String getUserBase()
    Return the base element for user searches.


    getUserByPattern

    protected org.apache.catalina.realm.User getUserByPattern(DirContext context,
                                                              String username,
                                                              String[] attrIds)
                throws NamingException
    Use the UserPattern configuration attribute to locate the directory entry for the user with the specified username and return a User object; otherwise return null.

    Parameters:
    context - The directory context
    username - The username
    attrIds - String[]containing names of attributes to retrieve.


    getUserBySearch

    protected org.apache.catalina.realm.User getUserBySearch(DirContext context,
                                                             String username,
                                                             String[] attrIds)
                throws NamingException
    Search the directory to return a User object containing information about the user with the specified username, if found in the directory; otherwise return null.

    Parameters:
    context - The directory context
    username - The username
    attrIds - String[]containing names of attributes to retrieve.


    getUserPassword

    public String getUserPassword()
    Return the password attribute used to retrieve the user password.


    getUserPattern

    public String getUserPattern()
    Return the message format pattern for selecting users in this Realm.


    getUserRoleName

    public String getUserRoleName()
    Return the user role name attribute name for this Realm.


    getUserSearch

    public String getUserSearch()
    Return the message format pattern for selecting users in this Realm.


    getUserSubtree

    public boolean getUserSubtree()
    Return the "search subtree for users" flag.


    open

    protected DirContext open()
                throws NamingException
    Open (if necessary) and return a connection to the configured directory server for this Realm.


    parseUserPatternString

    protected String[] parseUserPatternString(String userPatternString)
    Given a string containing LDAP patterns for user locations (separated by parentheses in a pseudo-LDAP search string format - "(location1)(location2)", returns an array of those paths. Real LDAP search strings are supported as well (though only the "|" "OR" type).

    Parameters:
    userPatternString - - a string LDAP search paths surrounded by parentheses


    release

    protected void release(DirContext context)
    Release our use of this connection so that it can be recycled.

    Parameters:
    context - The directory context to release


    setAlternateURL

    public void setAlternateURL(String alternateURL)
    Setter for property alternateURL.

    Parameters:
    alternateURL - New value of property alternateURL.


    setAuthentication

    public void setAuthentication(String authentication)
    Set the type of authentication to use.

    Parameters:
    authentication - The authentication


    setConnectionName

    public void setConnectionName(String connectionName)
    Set the connection username for this Realm.

    Parameters:
    connectionName - The new connection username


    setConnectionPassword

    public void setConnectionPassword(String connectionPassword)
    Set the connection password for this Realm.

    Parameters:
    connectionPassword - The new connection password


    setConnectionURL

    public void setConnectionURL(String connectionURL)
    Set the connection URL for this Realm.

    Parameters:
    connectionURL - The new connection URL


    setContextFactory

    public void setContextFactory(String contextFactory)
    Set the JNDI context factory for this Realm.

    Parameters:
    contextFactory - The new context factory


    setDerefAliases

    public void setDerefAliases(java.lang.String derefAliases)
    Set the value for derefAliases to be used when searching the directory.

    Parameters:
    derefAliases - New value of property derefAliases.


    setProtocol

    public void setProtocol(String protocol)
    Set the protocol for this Realm.

    Parameters:
    protocol - The new protocol.


    setReferrals

    public void setReferrals(String referrals)
    How do we handle JNDI referrals? ignore, follow, or throw (see javax.naming.Context.REFERRAL for more information).


    setRoleBase

    public void setRoleBase(String roleBase)
    Set the base element for role searches.

    Parameters:
    roleBase - The new base element


    setRoleName

    public void setRoleName(String roleName)
    Set the role name attribute name for this Realm.

    Parameters:
    roleName - The new role name attribute name


    setRoleSearch

    public void setRoleSearch(String roleSearch)
    Set the message format pattern for selecting roles in this Realm.

    Parameters:
    roleSearch - The new role search pattern


    setRoleSubtree

    public void setRoleSubtree(boolean roleSubtree)
    Set the "search subtree for roles" flag.

    Parameters:
    roleSubtree - The new search flag


    setUserBase

    public void setUserBase(String userBase)
    Set the base element for user searches.

    Parameters:
    userBase - The new base element


    setUserPassword

    public void setUserPassword(String userPassword)
    Set the password attribute used to retrieve the user password.

    Parameters:
    userPassword - The new password attribute


    setUserPattern

    public void setUserPattern(String userPattern)
    Set the message format pattern for selecting users in this Realm. This may be one simple pattern, or multiple patterns to be tried, separated by parentheses. (for example, either "cn={0}", or "(cn={0})(cn={0},o=myorg)" Full LDAP search strings are also supported, but only the "OR", "|" syntax, so "(|(cn={0})(cn={0},o=myorg))" is also valid. Complex search strings with &, etc are NOT supported.

    Parameters:
    userPattern - The new user pattern


    setUserRoleName

    public void setUserRoleName(String userRoleName)
    Set the user role name attribute name for this Realm.

    Parameters:
    userRoleName - The new userRole name attribute name


    setUserSearch

    public void setUserSearch(String userSearch)
    Set the message format pattern for selecting users in this Realm.

    Parameters:
    userSearch - The new user search pattern


    setUserSubtree

    public void setUserSubtree(boolean userSubtree)
    Set the "search subtree for users" flag.

    Parameters:
    userSubtree - The new search flag


    start

    public void start()
                throws LifecycleException
    Prepare for active use of the public methods of this Component.
    Specified by:
    start in interface Lifecycle
    Overrides:
    start in interface RealmBase

    Throws:
    LifecycleException - if this component detects a fatal error that prevents it from being started


    stop

    public void stop()
                throws LifecycleException
    Gracefully shut down active use of the public methods of this Component.
    Specified by:
    stop in interface Lifecycle
    Overrides:
    stop in interface RealmBase

    Throws:
    LifecycleException - if this component detects a fatal error that needs to be reported


    Copyright B) 2000-2003 Apache Software Foundation. All Rights Reserved.