Introduction

The Authenticator instances are used to authenticate the binding users. As of version 1.0, we only have two authenticators :

  1. Anonymous
  2. Simple

Authenticator Interface

The interface is quite simple. An implementor should implements 5 methods only, but as we also have an abstract class (AbstractAuthenticator) which handles some of the operations  :

method

description

init

Initialize the authenticator. Right now, it does nothing much than storing the configuration and its associated factory

destroy

Remove the configuration and the factory from the class

getAuthenticatorType

Get the Authenticator type (atm, "none" or "simple")

authenticate

Implemented in the implementing classes, this is the heart of the authentication mechanism

invalidateCache

Invalidate the cache to force the next password check to be done against the backend

Implementations 

Anonymous

The anonymous authenticator does nothing else than check that the server allows anonymous connexion. If they are not allowed, the server simply throw an exception.

The anonymous authentication differs from the simple authenticator in that we don't have a principal passed in the Bind request.
In this case, we will be authenticated immediatly, but it can be done through the SImpleAuthenticator too...

Funny enough, this is exactly what happens... As the authenticators are tried one by one, and as the SImpleAuthenticator comes first in the list, an anonymous bind is managed by the SimpleAuthenticator...

Simple

The simple authenticator compare the user password against the stored password. We use a cache to speedup this operation, which is used very frequently (for every bindRequest, including when the synchronization process is running).

Encrypted password are accepted.

The implemented algorithm is the following :

if the user has been stored in the cache
  then
    if his credential is the same than the one in the cache
      then return the stored principal from the cache
      else throw an error
  else
    Get the password from the backend
    if the passwords is the same
      then create a new principal for this user, store it in the cache and return it
      else
        if the stored password is encrypted
          then encrypt the user supplied password with the same mechanism
            if the encrypted password is equal to the one stored
              then create a new principal for this user, store it in the cache and return it
              else throw an error
          else throw an error

Usage 

Where and when are the authenticators declared and used in the Apache DS server ? The initialization process occurs when Spring is loading the MutableServerStartupConfiguration for the system partition.

The following class diagram expose the inheritence scheme for the configuration classes :


When the server is first started, an instance of the MutableServerStartupConfiguration class is created, which calls the setDefaultAuthenticatorConfigurations() method from the StartupConfiguration constructor, as shown in the following sequence diagram :

This method does register the two basic authentication mechanisms, Simple and Anonymous :

private void setDefaultAuthenticatorConfigurations()
    {
        Set set = new HashSet();

        // Anonymous
        set.add( new MutableAuthenticatorConfiguration( "Anonymous", new AnonymousAuthenticator() ) );

        // Simple
        set.add( new MutableAuthenticatorConfiguration( "Simple", new SimpleAuthenticator() ) );

        setAuthenticatorConfigurations( set );
    }

Evolution

The authenticators are currently static classes, and cannot be loaded dynamically. This is ok for Anonymous and Simple authentications, but if we want to add a new authenticator, we should provide a way for administrator to include a new authenticator into the server.

It would be very powerfull if such classes were loaded into the server as java classes and dynamically loaded on startup.

  • No labels