Login Extensions

From Dreamtsoft Wiki
Jump to: navigation, search

Login handling in F8

The handling of user login authentication in F8 is customizable to allow external systems to authenticate users. F8 allows the creation of "login modules" that handle authenticating users during login and setting up the session information (groups and attributes) after successful login. Each login module is called, in order, until one returns an indication that the user has been successfully validated or has failed validation. Each login module may return an ignored status, indicating that the login module does not handle the user. This allows different types of login handling based on the user name or other information provided in the login request.

Login Modules

A login module contains the following information:

Name
Name of the login module used for log messages
Description
Description of the login module
Login handling Class
The javascript class used to validate the user during login (see below for details of this class)

Login Processing

The login modules are processed in the order that is defined for the F8 instance. The login module for an instance contain the following information:

Login Module Name
The login module that is to be executed
On Failure
What to do if the login module returns failure. The authentation process can Continue Checking the next login module, or Stop and Fail Login to preven the user from logging in. See below
Order
Order of priority of the login modules (lower order numbers are called before higher order numbers)
Active
Flag indicating if this login module is active - if not active, the login module is not called during authentication

The authentication process

When a user needs to be validated by F8, it is supplied the username and password (and possibly additional information). F8 calls each of the login module's authenticate method from lowest order number to highest order number. The login modules return a string indiating the authentication status of success, failure or ignored. Handling of the status is described in this table:

Status On Failure Action Taken
success Continue Checking The user is valid and allowed to login. No further login modules are called.
Stop and Fail Login The user is valid and allowed to login. No further login modules are called.
failure Continue Checking The result is ignored and the next login module is called in order.
Stop and Fail Login The user is invalid and not allowed to login. No further login modules are called.
ignored Continue Checking The login module does not handle validation of this user. The next login module is called in order.
Stop and Fail Login The login module does not handle validation of this user. The next login module is called in order.

If all login modules are called and none have returned success, the user is considered invalid and the login fails.

Example login module

The login module class must contain an authenticate function that returns a string indicating the authentication status:

  • success - the user has been validated
  • failure - the user is not valid
  • ignore - the login module did not validate (or invalidate) the user

For example, the authenticate function may look like this:

   /**
    * Local User Login authentication
    */

   var F8LocalLogin = Class.create({
      /**
       * See if the user is in the user bucket with an empty auth_type
       */
      authenticate: function(helper, user, pass) {
         var userRecord = new FRecord('user');
         userRecord.addSearch('user_id', user);
         userRecord.search();
         if (userRecord.next() && (userRecord.auth_type.isNil())) {
            return helper.authValidateLocalUser(user, pass);
         }

         // Not a local user
         return 'ignored';
      },

      logout: function(userRecord) {
         // Handle any special logout processing if necessary here
      }  
   });

   module.exports = F8LocalLogin;

The helper that is passed to the authenticate method provides help for the authentication, including:

	/**
	 * Set the display name for the validated user
	 *
	 * @param name user name
	 */
	setUserName(String name)

	/**
	 * Set the user record id for the validated user (blank for no associated user record)
	 *
	 * @param id record id
	 */
	setUserRecordId(String id)

	/**
	 * Add a group that the validated user belongs to
	 *
	 * @param groupId id of group record user belongs to
	 */
	addGroup(String groupId)

	/**
	 * Set an attribute for the validated user's session
	 *
	 * @param name attribute name
	 * @param value attribute value
	 */
	setAttribute(String name, String value)

	/**
	 * Determine if a user/password combination is valid for a user in the F8 user bucket
	 *
	 * If the user is valid, the groups the user is associated with are set up for the user session along with
	 * the user display name (setUserName) and the user record id (setUserRecordId).
	 *
	 * @param user name of user to validate
	 * @param password cleartext password of user to validate
	 *
	 * @return status of validation ("success|failure")
	 */
	authValidateLocalUser(String user, String password)

	/**
	 * Determine if the user/password combination is valid for the user using the user's ldap directory
	 *
	 * @param user name of user to validate
	 * @param password cleartext password of user to validate
	 *
	 * @return status of the validation ("success|failure")
	 */
	authValidateLDAPUser(String user, String password)

Notice that there is an optional logout function that, if exists, will be called when a user logs out to allow any special logout processing that may be necessary. The login extension should check the userRecord to ensure that the user being logged out is one that is handled by this login extension (typically, by checking the user's auth_type value).