Class JndiLdapContextFactory
java.lang.Object
org.apache.shiro.realm.ldap.JndiLdapContextFactory
- All Implemented Interfaces:
LdapContextFactory
LdapContextFactory implementation using the default Sun/Oracle JNDI Ldap API, utilizing JNDI
environment properties and an InitialContext.
Configuration
This class basically wraps a default template JNDI environment properties Map. This properties map is the base configuration template used to acquire JNDILdapContext connections at runtime. The
getLdapContext(Object, Object) method implementation merges this default template with other properties
accessible at runtime only (for example per-method principals and credentials). The constructed runtime map is the
one used to acquire the LdapContext.
The template can be configured directly via the getEnvironment()/setEnvironment(java.util.Map)
properties directly if necessary, but it is usually more convenient to use the supporting wrapper get/set methods
for various environment properties. These wrapper methods interact with the environment
template on your behalf, leaving your configuration cleaner and easier to understand.
For example, consider the following two identical configurations:
[main] ldapRealm = org.apache.shiro.realm.ldap.DefaultLdapRealm ldapRealm.contextFactory.url = ldap://localhost:389 ldapRealm.contextFactory.authenticationMechanism = DIGEST-MD5and
[main] ldapRealm = org.apache.shiro.realm.ldap.DefaultLdapRealm ldapRealm.contextFactory.environment[java.naming.provider.url] = ldap://localhost:389 ldapRealm.contextFactory.environment[java.naming.security.authentication] = DIGEST-MD5As you can see, the 2nd configuration block is a little more difficult to read and also requires knowledge of the underlying JNDI Context property keys. The first is easier to read and understand. Note that occasionally it will be necessary to use the latter configuration style to set environment properties where no corresponding wrapper method exists. In this case, the hybrid approach is still a little easier to read. For example:
[main] ldapRealm = org.apache.shiro.realm.ldap.DefaultLdapRealm ldapRealm.contextFactory.url = ldap://localhost:389 ldapRealm.contextFactory.authenticationMechanism = DIGEST-MD5 ldapRealm.contextFactory.environment[some.other.obscure.jndi.key] = some value
- Since:
- 1.1
-
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionDefault no-argument constructor that initializes the backingenvironment templatewith thecontextFactoryClassNameequal tocom.sun.jndi.ldap.LdapCtxFactory(the Sun/Oracle default) and the defaultreferralbehavior tofollow. -
Method Summary
Modifier and TypeMethodDescriptionprotected LdapContextCreates and returns a newInitialLdapContextinstance.Returns the type of LDAP authentication mechanism to use when connecting to the LDAP server.Sets the name of the ContextFactory class to use.Returns the base JNDI environment template to use when acquiring an LDAP connection (anLdapContext).getLdapContext(Object principal, Object credentials) This implementation returns an LdapContext based on the configured JNDI/LDAP environment configuration.Returns the LDAP referral behavior when creating a connection.This implementation delegates togetLdapContext(Object, Object)using thesystemUsernameandsystemPasswordproperties as arguments.Returns the password of thesystemUsernamethat will be used when creating an LDAP connection used for authorization queries.Returns the system username that will be used when creating an LDAP connection used for authorization queries.getUrl()Returns the LDAP url to connect to.protected booleanisPoolingConnections(Object principal) Returnstrueif LDAP connection pooling should be used when acquiring a connection based on the specified account principal,falseotherwise.booleanReturns whether or not connection pooling should be used when possible and appropriate.voidsetAuthenticationMechanism(String authenticationMechanism) Sets the type of LDAP authentication mechanism to use when connecting to the LDAP server.voidsetContextFactoryClassName(String contextFactoryClassName) The name of the ContextFactory class to use.voidsetEnvironment(Map env) Sets the base JNDI environment template to use when acquiring LDAP connections.voidsetPoolingEnabled(boolean poolingEnabled) Sets whether or not connection pooling should be used when possible and appropriate.voidsetReferral(String referral) Sets the LDAP referral behavior when creating a connection.voidsetSystemPassword(String systemPassword) Sets the password of thesystemUsernamethat will be used when creating an LDAP connection used for authorization queries.voidsetSystemUsername(String systemUsername) Sets the system username that will be used when creating an LDAP connection used for authorization queries.voidThe LDAP url to connect to.protected voidvalidateAuthenticationInfo(Hashtable<String, Object> environment) Validates the configuration in the JNDIenvironmentsettings and throws an exception if a problem exists.
-
Field Details
-
SUN_CONNECTION_POOLING_PROPERTY
The Sun LDAP property used to enable connection pooling. This is used in the default implementation to enable LDAP connection pooling.- See Also:
-
DEFAULT_CONTEXT_FACTORY_CLASS_NAME
- See Also:
-
SIMPLE_AUTHENTICATION_MECHANISM_NAME
- See Also:
-
DEFAULT_REFERRAL
- See Also:
-
-
Constructor Details
-
JndiLdapContextFactory
public JndiLdapContextFactory()Default no-argument constructor that initializes the backingenvironment templatewith thecontextFactoryClassNameequal tocom.sun.jndi.ldap.LdapCtxFactory(the Sun/Oracle default) and the defaultreferralbehavior tofollow.
-
-
Method Details
-
setAuthenticationMechanism
Sets the type of LDAP authentication mechanism to use when connecting to the LDAP server. This is a wrapper method for setting the JNDIenvironment template'sContext.SECURITY_AUTHENTICATIONproperty. "none" (i.e. anonymous) and "simple" authentications are supported automatically and don't need to be configured via this property. However, if you require a different mechanism, such as a SASL or External mechanism, you must configure that explicitly via this property. See the JNDI LDAP Authentication Mechanisms for more information.- Parameters:
authenticationMechanism- the type of LDAP authentication to perform.- See Also:
-
getAuthenticationMechanism
Returns the type of LDAP authentication mechanism to use when connecting to the LDAP server. This is a wrapper method for getting the JNDIenvironment template'sContext.SECURITY_AUTHENTICATIONproperty. If this property remains un-configured (i.e.nullindicating thesetAuthenticationMechanism(String)method wasn't used), this indicates that the default JNDI "none" (anonymous) and "simple" authentications are supported automatically. Any non-null value returned represents an explicitly configured mechanism (e.g. a SASL or external mechanism). See the JNDI LDAP Authentication Mechanisms for more information.- Returns:
- the type of LDAP authentication mechanism to use when connecting to the LDAP server.
- See Also:
-
setContextFactoryClassName
The name of the ContextFactory class to use. This defaults to the SUN LDAP JNDI implementation but can be overridden to use custom LDAP factories. This is a wrapper method for setting the JNDI environment'sContext.INITIAL_CONTEXT_FACTORYproperty.- Parameters:
contextFactoryClassName- the context factory that should be used.
-
getContextFactoryClassName
Sets the name of the ContextFactory class to use. This defaults to the SUN LDAP JNDI implementation but can be overridden to use custom LDAP factories. This is a wrapper method for getting the JNDI environment'sContext.INITIAL_CONTEXT_FACTORYproperty.- Returns:
- the name of the ContextFactory class to use.
-
getEnvironment
Returns the base JNDI environment template to use when acquiring an LDAP connection (anLdapContext). This property is the base configuration template to use for all connections. This template is then merged with appropriate runtime values as necessary in thegetLdapContext(Object, Object)implementation. The merged environment instance is what is used to acquire theLdapContextat runtime. Most other get/set methods in this class act as thin proxy wrappers that interact with this property. The benefit of using them is you have an easier-to-use configuration mechanism compared to setting map properties based on JNDI context keys.- Returns:
- the base JNDI environment template to use when acquiring an LDAP connection (an
LdapContext)
-
setEnvironment
Sets the base JNDI environment template to use when acquiring LDAP connections. It is typically more common to use the other get/set methods in this class to set individual environment settings rather than use this method, but it is available for advanced users that want full control over the base JNDI environment settings. Note that this template only represents the base/default environment settings. It is then merged with appropriate runtime values as necessary in thegetLdapContext(Object, Object)implementation. The merged environment instance is what is used to acquire the connection (LdapContext) at runtime.- Parameters:
env- the base JNDI environment template to use when acquiring LDAP connections.
-
isPoolingEnabled
Returns whether or not connection pooling should be used when possible and appropriate. This property is NOT backed by theenvironment templatelike most other properties in this class. It is a flag to indicate that pooling is preferred. The default value istrue. However, pooling will only actually be enabled if this property istrueand the connection being created is for thesystemUsernameuser. Connection pooling is not used for general authentication attempts by application end-users because the probability of re-use for that same user-specific connection after an authentication attempt is extremely low. If this attribute istrueand it has been determined that the connection is being made with thesystemUsername, thegetLdapContext(Object, Object)implementation will set the Sun/Oracle-specificcom.sun.jndi.ldap.connect.poolenvironment property to "true". This means setting this property is only likely to work if using the Sun/Oracle default context factory class (i.e. not using a customcontextFactoryClassName).- Returns:
- whether or not connection pooling should be used when possible and appropriate
-
setPoolingEnabled
Sets whether or not connection pooling should be used when possible and appropriate. This property is NOT a wrapper to theenvironment templatelike most other properties in this class. It is a flag to indicate that pooling is preferred. The default value istrue. However, pooling will only actually be enabled if this property istrueand the connection being created is for thesystemUsernameuser. Connection pooling is not used for general authentication attempts by application end-users because the probability of re-use for that same user-specific connection after an authentication attempt is extremely low. If this attribute istrueand it has been determined that the connection is being made with thesystemUsername, thegetLdapContext(Object, Object)implementation will set the Sun/Oracle-specificcom.sun.jndi.ldap.connect.poolenvironment property to "true". This means setting this property is only likely to work if using the Sun/Oracle default context factory class (i.e. not using a customcontextFactoryClassName).- Parameters:
poolingEnabled- whether or not connection pooling should be used when possible and appropriate
-
setReferral
Sets the LDAP referral behavior when creating a connection. Defaults tofollow. See the Sun/Oracle LDAP referral documentation for more.- Parameters:
referral- the referral property.- See Also:
-
getReferral
Returns the LDAP referral behavior when creating a connection. Defaults tofollow. See the Sun/Oracle LDAP referral documentation for more.- Returns:
- the LDAP referral behavior when creating a connection.
- See Also:
-
setUrl
-
getUrl
-
setSystemPassword
Sets the password of thesystemUsernamethat will be used when creating an LDAP connection used for authorization queries. Note that setting this property is not required if the calling LDAP Realm does not perform authorization checks.- Parameters:
systemPassword- the password of thesystemUsernamethat will be used when creating an LDAP connection used for authorization queries.
-
getSystemPassword
Returns the password of thesystemUsernamethat will be used when creating an LDAP connection used for authorization queries. Note that setting this property is not required if the calling LDAP Realm does not perform authorization checks.- Returns:
- the password of the
systemUsernamethat will be used when creating an LDAP connection used for authorization queries.
-
setSystemUsername
Sets the system username that will be used when creating an LDAP connection used for authorization queries. The user must have the ability to query for authorization data for any application user. Note that setting this property is not required if the calling LDAP Realm does not perform authorization checks.- Parameters:
systemUsername- the system username that will be used when creating an LDAP connection used for authorization queries.
-
getSystemUsername
Returns the system username that will be used when creating an LDAP connection used for authorization queries. The user must have the ability to query for authorization data for any application user. Note that setting this property is not required if the calling LDAP Realm does not perform authorization checks.- Returns:
- the system username that will be used when creating an LDAP connection used for authorization queries.
-
getSystemLdapContext
This implementation delegates togetLdapContext(Object, Object)using thesystemUsernameandsystemPasswordproperties as arguments.- Specified by:
getSystemLdapContextin interfaceLdapContextFactory- Returns:
- the system LdapContext
- Throws:
NamingException- if there is a problem connecting to the LDAP directory
-
isPoolingConnections
Returnstrueif LDAP connection pooling should be used when acquiring a connection based on the specified account principal,falseotherwise. This implementation returnstrueonly ifisPoolingEnabled()and the principal equals thegetSystemUsername(). The reasoning behind this is that connection pooling is not desirable for general authentication attempts by application end-users because the probability of re-use for that same user-specific connection after an authentication attempt is extremely low.- Parameters:
principal- the principal under which the connection will be made- Returns:
trueif LDAP connection pooling should be used when acquiring a connection based on the specified account principal,falseotherwise.
-
getLdapContext
public LdapContext getLdapContext(Object principal, Object credentials) throws NamingException, IllegalStateException This implementation returns an LdapContext based on the configured JNDI/LDAP environment configuration. The environment (Map) used at runtime is created by merging the default/configuredenvironment templatewith some runtime values as necessary (e.g. a principal and credential available at runtime only). After the merged Map instance is created, the LdapContext connection iscreatedand returned.- Specified by:
getLdapContextin interfaceLdapContextFactory- Parameters:
principal- the principal to use when acquiring a connection to the LDAP directorycredentials- the credentials (password, X.509 certificate, etc.) to use when acquiring a connection to the LDAP directory- Returns:
- the acquired
LdapContextconnection bound using the specified principal and credentials. - Throws:
NamingExceptionIllegalStateException
-
createLdapContext
Creates and returns a newInitialLdapContextinstance. This method exists primarily to support testing where a mock LdapContext can be returned instead of actually creating a connection, but subclasses are free to provide a different implementation if necessary.- Parameters:
env- the JNDI environment settings used to create the LDAP connection- Returns:
- an LdapConnection
- Throws:
NamingException- if a problem occurs creating the connection
-
validateAuthenticationInfo
protected void validateAuthenticationInfo(Hashtable<String, Object> environment) throws AuthenticationExceptionValidates the configuration in the JNDIenvironmentsettings and throws an exception if a problem exists. This implementation will throw aAuthenticationExceptionif the authentication mechanism is set to 'simple', the principal is non-empty, and the credentials are empty (as per rfc4513 section-5.1.2).- Parameters:
environment- the JNDI environment settings to be validated- Throws:
AuthenticationException- if a configuration problem is detected
-