org.apache.catalina.realm

Class JNDIRealm

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:

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://issues.apache.org/bugzilla/show_bug.cgi?id=11210 . With luck, Netscape has updated their provider code and this is not an issue.

Version: $Revision: 898707 $ $Date: 2010-01-13 11:37:53 +0100 (Wed, 13 Jan 2010) $

Author: John Holman Craig R. McClanahan

Field Summary
protected booleanadCompat
Should we ignore PartialResultExceptions when iterating over NamingEnumerations?
protected StringalternateURL
An alternate URL, to which, we should connect if connectionURL fails.
protected Stringauthentication
The type of authentication to use
protected StringcommonRole
Add this role to every authenticated user
protected intconnectionAttempt
The number of connection attempts.
protected StringconnectionName
The connection username for the server we will contact.
protected StringconnectionPassword
The connection password for the server we will contact.
protected StringconnectionTimeout
The timeout, in milliseconds, to use when trying to create a connection to the directory.
protected StringconnectionURL
The connection URL for the server we will contact.
protected DirContextcontext
The directory context linking us to our directory server.
protected StringcontextFactory
The JNDI context factory used to acquire our InitialContext.
protected StringderefAliases
How aliases should be dereferenced during search operations.
static StringDEREF_ALIASES
Constant that holds the name of the environment property for specifying the manner in which aliases should be dereferenced.
protected static Stringinfo
Descriptive information about this Realm implementation.
protected static Stringname
Descriptive information about this Realm implementation.
protected Stringprotocol
The protocol that will be used in the communication with the directory server.
protected Stringreferrals
How should we handle referrals?
protected StringroleBase
The base element for role searches.
protected MessageFormatroleFormat
The MessageFormat object associated with the current roleSearch.
protected StringroleName
The name of the attribute containing roles held elsewhere
protected booleanroleNested
Should we look for nested group in order to determine roles?
protected StringroleSearch
The message format used to select roles for a user, with "{0}" marking the spot where the distinguished name of the user goes.
protected booleanroleSubtree
Should we search the entire subtree for matching memberships?
protected StringuserBase
The base element for user searches.
protected StringuserPassword
The attribute name used to retrieve the user password.
protected StringuserPattern
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 StringuserRoleName
The name of an attribute in the user's entry containing roles for that user
protected StringuserSearch
The message format used to search for a user, with "{0}" marking the spot where the username goes.
protected MessageFormatuserSearchFormat
The MessageFormat object associated with the current userSearch.
protected booleanuserSubtree
Should we search the entire subtree for matching users?
Method Summary
Principalauthenticate(String username, String credentials)
Return the Principal associated with the specified username and credentials, if there is one; otherwise return null.
Principalauthenticate(DirContext context, String username, String credentials)
Return the Principal associated with the specified username and credentials, if there is one; otherwise return null.
protected booleanbindAsUser(DirContext context, User user, String credentials)
Check credentials by binding to the directory as the user
protected booleancheckCredentials(DirContext context, User user, String credentials)
Check whether the given User can be authenticated with the given credentials.
protected voidclose(DirContext context)
Close any open connection to the directory server for this Realm.
protected booleancompareCredentials(DirContext context, User info, String credentials)
Check whether the credentials presented by the user match those retrieved from the directory.
protected StringdoRFC2254Encoding(String inString)
Given an LDAP search string, returns the string with certain characters escaped according to RFC 2254 guidelines.
booleangetAdCompat()
Returns the current settings for handling PartialResultExceptions
StringgetAlternateURL()
Getter for property alternateURL.
StringgetAuthentication()
Return the type of authentication to use.
StringgetCommonRole()
Return the common role
StringgetConnectionName()
Return the connection username for this Realm.
StringgetConnectionPassword()
Return the connection password for this Realm.
StringgetConnectionTimeout()
Return the connection timeout.
StringgetConnectionURL()
Return the connection URL for this Realm.
StringgetContextFactory()
Return the JNDI context factory for this Realm.
StringgetDerefAliases()
Return the derefAliases setting to be used.
protected Hashtable<String,String>getDirectoryContextEnvironment()
Create our directory context configuration.
protected StringgetDistinguishedName(DirContext context, String base, SearchResult result)
Returns the distinguished name of a search result.
protected StringgetName()
Return a short name for this Realm implementation.
protected StringgetPassword(String username)
Return the password associated with the given principal's user name.
protected PrincipalgetPrincipal(String username)
Return the Principal associated with the given user name.
protected PrincipalgetPrincipal(DirContext context, String username)
Return the Principal associated with the given user name.
StringgetProtocol()
Return the protocol to be used.
StringgetReferrals()
Returns the current settings for handling JNDI referrals.
StringgetRoleBase()
Return the base element for role searches.
StringgetRoleName()
Return the role name attribute name for this Realm.
booleangetRoleNested()
Return the "The nested group search flag" flag.
protected List<String>getRoles(DirContext context, User user)
Return a List of roles associated with the given User.
StringgetRoleSearch()
Return the message format pattern for selecting roles in this Realm.
booleangetRoleSubtree()
Return the "search subtree for roles" flag.
protected UsergetUser(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.
protected UsergetUser(DirContext context, String username, String credentials)
Return a User object containing information about the user with the specified username, if found in the directory; otherwise return null.
protected UsergetUser(DirContext context, String username, String credentials, int curUserPattern)
Return a User object containing information about the user with the specified username, if found in the directory; otherwise return null.
StringgetUserBase()
Return the base element for user searches.
protected UsergetUserByPattern(DirContext context, String username, String[] attrIds, String dn)
Use the distinguished name to locate the directory entry for the user with the specified username and return a User object; otherwise return null.
protected UsergetUserByPattern(DirContext context, String username, String credentials, String[] attrIds, int curUserPattern)
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 UsergetUserBySearch(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.
StringgetUserPassword()
Return the password attribute used to retrieve the user password.
StringgetUserPattern()
Return the message format pattern for selecting users in this Realm.
StringgetUserRoleName()
Return the user role name attribute name for this Realm.
StringgetUserSearch()
Return the message format pattern for selecting users in this Realm.
booleangetUserSubtree()
Return the "search subtree for users" flag.
protected DirContextopen()
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 voidrelease(DirContext context)
Release our use of this connection so that it can be recycled.
voidsetAdCompat(boolean adCompat)
How do we handle PartialResultExceptions?
voidsetAlternateURL(String alternateURL)
Setter for property alternateURL.
voidsetAuthentication(String authentication)
Set the type of authentication to use.
voidsetCommonRole(String commonRole)
Set the common role
voidsetConnectionName(String connectionName)
Set the connection username for this Realm.
voidsetConnectionPassword(String connectionPassword)
Set the connection password for this Realm.
voidsetConnectionTimeout(String timeout)
Set the connection timeout.
voidsetConnectionURL(String connectionURL)
Set the connection URL for this Realm.
voidsetContextFactory(String contextFactory)
Set the JNDI context factory for this Realm.
voidsetDerefAliases(String derefAliases)
Set the value for derefAliases to be used when searching the directory.
voidsetProtocol(String protocol)
Set the protocol for this Realm.
voidsetReferrals(String referrals)
How do we handle JNDI referrals?
voidsetRoleBase(String roleBase)
Set the base element for role searches.
voidsetRoleName(String roleName)
Set the role name attribute name for this Realm.
voidsetRoleNested(boolean roleNested)
Set the "search subtree for roles" flag.
voidsetRoleSearch(String roleSearch)
Set the message format pattern for selecting roles in this Realm.
voidsetRoleSubtree(boolean roleSubtree)
Set the "search subtree for roles" flag.
voidsetUserBase(String userBase)
Set the base element for user searches.
voidsetUserPassword(String userPassword)
Set the password attribute used to retrieve the user password.
voidsetUserPattern(String userPattern)
Set the message format pattern for selecting users in this Realm.
voidsetUserRoleName(String userRoleName)
Set the user role name attribute name for this Realm.
voidsetUserSearch(String userSearch)
Set the message format pattern for selecting users in this Realm.
voidsetUserSubtree(boolean userSubtree)
Set the "search subtree for users" flag.
voidstart()
Prepare for active use of the public methods of this Component.
voidstop()
Gracefully shut down active use of the public methods of this Component.

Field Detail

adCompat

protected boolean adCompat
Should we ignore PartialResultExceptions when iterating over NamingEnumerations? Microsoft Active Directory often returns referrals, which lead to PartialResultExceptions. Unfortunately there's no stable way to detect, if the Exceptions really come from an AD referral. Set to true to ignore PartialResultExceptions.

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

commonRole

protected String commonRole
Add this role to every authenticated user

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.

connectionTimeout

protected String connectionTimeout
The timeout, in milliseconds, to use when trying to create a connection to the directory. The default is 5000 (5 seconds).

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.

derefAliases

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

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.

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 often returns referrals. If you need to follow them set referrals to "follow". Caution: if your DNS is not part of AD, the LDAP client lib might try to resolve your domain name in DNS to find another LDAP server.

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

roleNested

protected boolean roleNested
Should we look for nested group in order to determine roles?

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 Detail

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.

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

authenticate

public 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.

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

Throws: NamingException if a directory server error occurs

bindAsUser

protected boolean bindAsUser(DirContext context, User user, String credentials)
Check credentials by binding to the directory as the user

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

Throws: NamingException if a directory server error occurs

checkCredentials

protected boolean checkCredentials(DirContext context, User user, String credentials)
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

Throws: NamingException if a directory server error occurs

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, User info, String credentials)
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

Throws: NamingException if a directory server error occurs

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

getAdCompat

public boolean getAdCompat()
Returns the current settings for handling PartialResultExceptions

getAlternateURL

public String getAlternateURL()
Getter for property alternateURL.

Returns: Value of property alternateURL.

getAuthentication

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

getCommonRole

public String getCommonRole()
Return the common role

getConnectionName

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

getConnectionPassword

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

getConnectionTimeout

public String getConnectionTimeout()
Return the connection timeout.

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 String getDerefAliases()
Return the derefAliases setting to be used.

getDirectoryContextEnvironment

protected Hashtable<String,String> getDirectoryContextEnvironment()
Create our directory context configuration.

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

getDistinguishedName

protected String getDistinguishedName(DirContext context, String base, SearchResult result)
Returns the distinguished name of a search result.

Parameters: context Our DirContext base The base DN result The search result

Returns: String containing the distinguished name

getName

protected String getName()
Return a short name for this Realm implementation.

getPassword

protected String getPassword(String username)
Return the password associated with the given principal's user name.

getPrincipal

protected Principal getPrincipal(String username)
Return the Principal associated with the given user name.

getPrincipal

protected Principal getPrincipal(DirContext context, String username)
Return the Principal associated with the given user name.

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.

getRoleNested

public boolean getRoleNested()
Return the "The nested group search flag" flag.

getRoles

protected List<String> getRoles(DirContext context, User user)
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

Throws: NamingException if a directory server error occurs

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.

getUser

protected 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.

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

Throws: NamingException if a directory server error occurs

See Also: JNDIRealm

getUser

protected User getUser(DirContext context, String username, String credentials)
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 Username to be looked up credentials User credentials (optional)

Throws: NamingException if a directory server error occurs

See Also: JNDIRealm

getUser

protected User getUser(DirContext context, String username, String credentials, int curUserPattern)
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 credentials User credentials (optional) curUserPattern Index into userPatternFormatArray

Throws: NamingException if a directory server error occurs

getUserBase

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

getUserByPattern

protected User getUserByPattern(DirContext context, String username, String[] attrIds, String dn)
Use the distinguished name 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 dn Distinguished name of the user retrieve.

Throws: NamingException if a directory server error occurs

getUserByPattern

protected User getUserByPattern(DirContext context, String username, String credentials, String[] attrIds, int curUserPattern)
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 credentials User credentials (optional) attrIds String[]containing names of attributes to curUserPattern Index into userPatternFormatArray

Throws: NamingException if a directory server error occurs

See Also: (DirContext, String, String[], String)

getUserBySearch

protected 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.

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

Throws: NamingException if a directory server error occurs

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()
Open (if necessary) and return a connection to the configured directory server for this Realm.

Throws: NamingException if a directory server error occurs

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

setAdCompat

public void setAdCompat(boolean adCompat)
How do we handle PartialResultExceptions? True: ignore all PartialResultExceptions.

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

setCommonRole

public void setCommonRole(String commonRole)
Set the common role

Parameters: commonRole The common role

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

setConnectionTimeout

public void setConnectionTimeout(String timeout)
Set the connection timeout.

Parameters: timeout The new connection timeout

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(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

setRoleNested

public void setRoleNested(boolean roleNested)
Set the "search subtree for roles" flag.

Parameters: roleNested The nested group search flag

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()
Prepare for active use of the public methods of this Component.

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

stop

public void stop()
Gracefully shut down active use of the public methods of this Component.

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

Copyright © 2000-2011 Apache Software Foundation. All Rights Reserved.