Class JndiLdapContextFactory

  • All Implemented Interfaces:
    LdapContextFactory

    public class JndiLdapContextFactory
    extends 
    implements LdapContextFactory
    LdapContextFactory implementation using the default Sun/Oracle JNDI Ldap API, utilizing JNDI environment properties and an .

    Configuration

    This class basically wraps a default template JNDI environment properties Map. This properties map is the base configuration template used to acquire JNDI 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 .

    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-MD5
     
    and
     [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-MD5
     
    As 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
    • Method Summary

      All Methods Instance Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      protected  env)
      Creates and returns a new instance.
      getAuthenticationMechanism()
      Returns the type of LDAP authentication mechanism to use when connecting to the LDAP server.
      getContextFactoryClassName()
      Sets the name of the ContextFactory class to use.
      getEnvironment()
      Returns the base JNDI environment template to use when acquiring an LDAP connection (an ).
       principal,  credentials)
      This implementation returns an LdapContext based on the configured JNDI/LDAP environment configuration.
       username,  password)
      Deprecated.
      the getLdapContext(Object, Object) method should be used in all cases to ensure more than String principals and credentials can be used.
      getReferral()
      Returns the LDAP referral behavior when creating a connection.
      getSystemLdapContext()
      This implementation delegates to getLdapContext(Object, Object) using the systemUsername and systemPassword properties as arguments.
      getSystemPassword()
      Returns the password of the systemUsername 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.
      getUrl()
      Returns the LDAP url to connect to.
      protected boolean  principal)
      Returns true if LDAP connection pooling should be used when acquiring a connection based on the specified account principal, false otherwise.
      boolean isPoolingEnabled()
      Returns whether or not connection pooling should be used when possible and appropriate.
      void  authenticationMechanism)
      Sets the type of LDAP authentication mechanism to use when connecting to the LDAP server.
      void  contextFactoryClassName)
      The name of the ContextFactory class to use.
      void  env)
      Sets the base JNDI environment template to use when acquiring LDAP connections.
      void setPoolingEnabled​(boolean poolingEnabled)
      Sets whether or not connection pooling should be used when possible and appropriate.
      void  referral)
      Sets the LDAP referral behavior when creating a connection.
      void  systemPassword)
      Sets the password of the systemUsername that will be used when creating an LDAP connection used for authorization queries.
      void  systemUsername)
      Sets the system username that will be used when creating an LDAP connection used for authorization queries.
      void  url)
      The LDAP url to connect to.
      protected void <,​> environment)
      Validates the configuration in the JNDI environment settings and throws an exception if a problem exists.
      • Methods inherited from class java.lang.

        , , , , , , , , , ,
    • Field Detail

      • SUN_CONNECTION_POOLING_PROPERTY

        protected static final  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:
        Constant Field Values
      • DEFAULT_CONTEXT_FACTORY_CLASS_NAME

        protected static final  DEFAULT_CONTEXT_FACTORY_CLASS_NAME
        See Also:
        Constant Field Values
      • SIMPLE_AUTHENTICATION_MECHANISM_NAME

        protected static final  SIMPLE_AUTHENTICATION_MECHANISM_NAME
        See Also:
        Constant Field Values
    • Constructor Detail

      • JndiLdapContextFactory

        public JndiLdapContextFactory()
        Default no-argument constructor that initializes the backing environment template with the contextFactoryClassName equal to com.sun.jndi.ldap.LdapCtxFactory (the Sun/Oracle default) and the default referral behavior to follow.
    • Method Detail

      • setAuthenticationMechanism

        public void setAuthenticationMechanism​( authenticationMechanism)
        Sets the type of LDAP authentication mechanism to use when connecting to the LDAP server. This is a wrapper method for setting the JNDI environment template's property.

        "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 for more information.

        Parameters:
        authenticationMechanism - the type of LDAP authentication to perform.
        See Also:
      • getAuthenticationMechanism

        public  getAuthenticationMechanism()
        Returns the type of LDAP authentication mechanism to use when connecting to the LDAP server. This is a wrapper method for getting the JNDI environment template's property.

        If this property remains un-configured (i.e. null indicating the setAuthenticationMechanism(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 for more information.

        Returns:
        the type of LDAP authentication mechanism to use when connecting to the LDAP server.
        See Also:
      • setContextFactoryClassName

        public void setContextFactoryClassName​( contextFactoryClassName)
        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's property.

        Parameters:
        contextFactoryClassName - the context factory that should be used.
      • getContextFactoryClassName

        public  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's property.

        Returns:
        the name of the ContextFactory class to use.
      • getEnvironment

        public  getEnvironment()
        Returns the base JNDI environment template to use when acquiring an LDAP connection (an ). This property is the base configuration template to use for all connections. This template is then merged with appropriate runtime values as necessary in the getLdapContext(Object, Object) implementation. The merged environment instance is what is used to acquire the at 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 )
      • setEnvironment

        public void setEnvironment​( env)
        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 the getLdapContext(Object, Object) implementation. The merged environment instance is what is used to acquire the connection () at runtime.

        Parameters:
        env - the base JNDI environment template to use when acquiring LDAP connections.
      • isPoolingEnabled

        public boolean isPoolingEnabled()
        Returns whether or not connection pooling should be used when possible and appropriate. This property is NOT backed by the environment template like most other properties in this class. It is a flag to indicate that pooling is preferred. The default value is true.

        However, pooling will only actually be enabled if this property is true and the connection being created is for the systemUsername user. 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 is true and it has been determined that the connection is being made with the systemUsername, the getLdapContext(Object, Object) implementation will set the Sun/Oracle-specific com.sun.jndi.ldap.connect.pool environment 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 custom contextFactoryClassName).

        Returns:
        whether or not connection pooling should be used when possible and appropriate
      • setPoolingEnabled

        public void setPoolingEnabled​(boolean poolingEnabled)
        Sets whether or not connection pooling should be used when possible and appropriate. This property is NOT a wrapper to the environment template like most other properties in this class. It is a flag to indicate that pooling is preferred. The default value is true.

        However, pooling will only actually be enabled if this property is true and the connection being created is for the systemUsername user. 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 is true and it has been determined that the connection is being made with the systemUsername, the getLdapContext(Object, Object) implementation will set the Sun/Oracle-specific com.sun.jndi.ldap.connect.pool environment 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 custom contextFactoryClassName).

        Parameters:
        poolingEnabled - whether or not connection pooling should be used when possible and appropriate
      • setReferral

        public void setReferral​( referral)
        Sets the LDAP referral behavior when creating a connection. Defaults to follow. See the Sun/Oracle LDAP for more.
        Parameters:
        referral - the referral property.
        See Also:
      • getReferral

        public  getReferral()
        Returns the LDAP referral behavior when creating a connection. Defaults to follow. See the Sun/Oracle LDAP for more.
        Returns:
        the LDAP referral behavior when creating a connection.
        See Also:
      • setUrl

        public void setUrl​( url)
        The LDAP url to connect to. (e.g. ldap://<ldapDirectoryHostname>:<port>). This must be configured.
        Parameters:
        url - the LDAP url to connect to. (e.g. ldap://<ldapDirectoryHostname>:<port>)
      • getUrl

        public  getUrl()
        Returns the LDAP url to connect to. (e.g. ldap://<ldapDirectoryHostname>:<port>). This must be configured.
        Returns:
        the LDAP url to connect to. (e.g. ldap://<ldapDirectoryHostname>:<port>)
      • setSystemPassword

        public void setSystemPassword​( systemPassword)
        Sets the password of the systemUsername that 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 the systemUsername that will be used when creating an LDAP connection used for authorization queries.
      • getSystemPassword

        public  getSystemPassword()
        Returns the password of the systemUsername that 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 systemUsername that will be used when creating an LDAP connection used for authorization queries.
      • setSystemUsername

        public void setSystemUsername​( systemUsername)
        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

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

        public  getLdapContext​( username,
                                           password)
                                   throws 
        Deprecated.
        the getLdapContext(Object, Object) method should be used in all cases to ensure more than String principals and credentials can be used. Shiro no longer calls this method - it will be removed before the 2.0 release.
        Deprecated - use getLdapContext(Object, Object) instead. This will be removed before Apache Shiro 2.0.
        Specified by:
        getLdapContext in interface LdapContextFactory
        Parameters:
        username - the username to use when creating the connection.
        password - the password to use when creating the connection.
        Returns:
        a LdapContext bound using the given username and password.
        Throws:
        - if there is an error creating the context.
      • isPoolingConnections

        protected boolean isPoolingConnections​( principal)
        Returns true if LDAP connection pooling should be used when acquiring a connection based on the specified account principal, false otherwise.

        This implementation returns true only if isPoolingEnabled() and the principal equals the getSystemUsername(). 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:
        true if LDAP connection pooling should be used when acquiring a connection based on the specified account principal, false otherwise.
      • getLdapContext

        public  getLdapContext​( principal,
                                           credentials)
                                   throws ,
                                          
        This implementation returns an LdapContext based on the configured JNDI/LDAP environment configuration. The environnmet (Map) used at runtime is created by merging the default/configured environment template with 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 is created and returned.

        Specified by:
        getLdapContext in interface LdapContextFactory
        Parameters:
        principal - the principal to use when acquiring a connection to the LDAP directory
        credentials - the credentials (password, X.509 certificate, etc) to use when acquiring a connection to the LDAP directory
        Returns:
        the acquired LdapContext connection bound using the specified principal and credentials.
        Throws:
      • createLdapContext

        protected  createLdapContext​( env)
                                         throws 
        Creates and returns a new instance. 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:
        - if a problem occurs creating the connection
      • validateAuthenticationInfo

        protected void validateAuthenticationInfo​(<,​> environment)
                                           throws 
        Validates the configuration in the JNDI environment settings and throws an exception if a problem exists.

        This implementation will throw a if the authentication mechanism is set to 'simple', the principal is non-empty, and the credentials are empty (as per ).

        Parameters:
        environment - the JNDI environment settings to be validated
        Throws:
        - if a configuration problem is detected