Skip to main content
Skip table of contents

Writing an authenticator for the Access Management System

The Access Management System comes with several authenticators, but can be extended by adding more.

An authenticator must satisfy the following condition:

  • An authenticator must be placed in the same directory as other authenticator at engine/models/authenticators and comes with the prefix of _authenticator at the end. (eg facebook_authenticator.php)
  • An authenticator must extends the Authenticator class and include the engine/models/authenticator.php file
  • An authenticator must have a function called authenticate that will execute $this->return_roles($role) where $role is the role that successfully authenticated to, or else throw an exception that will be catch and return as an error message

Take for instance the Facebook Authentication file engine/models/authenticators/facebook_authenticator.php

PHP
<?php
/**
 * Authenticator for Social Accounts / Facebook
 * @author  Minh Duc Nguyen <minh.nguyen@ands.org.au>
 */
require_once('engine/models/authenticator.php');
class Facebook_authenticator extends Authenticator {
	public function authenticate() {
		$provider = 'Facebook';
		$this->load->library('HybridAuthLib');
		try{
			$service = $this->hybridauthlib->authenticate($provider);
			if($service->isUserConnected()) {
				$user_profile = $service->getUserProfile();
				$access_token = $service->getAccessToken();
				$access_token = $access_token['access_token'];
				$allow = array('identifier', 'displayName', 'photoURL', 'firstName', 'lastName', 'email');
				foreach($user_profile as $u=>$thing){
					if(!in_array($u, $allow)) unset($user_profile->{$u});
				}
				
				//check if there's an existing profile
				$user = $this->cosi_db->get_where('roles', array('role_id'=>$user_profile->identifier, 'authentication_service_id'=>'AUTHENTICATION_SOCIAL_FACEBOOK'));
				if($user->num_rows() > 0) {
					//found existing user, maybe updating some logs here
				} else {
					//create a new role
					$data = array(
						'role_id' => $user_profile->identifier,
						'role_type_id' => 'ROLE_USER',
						'authentication_service_id' => 'AUTHENTICATION_SOCIAL_FACEBOOK',
						'enabled' => DB_TRUE,
						'name' => $user_profile->displayName,
						'oauth_access_token' => $access_token,
						'oauth_data' => json_encode($user_profile),
						'email' => $user_profile->email
					);
					$this->cosi_db->insert('roles',$data);
					$user = $this->cosi_db->get_where('roles', array('role_id'=>$user_profile->identifier, 'authentication_service_id'=>'AUTHENTICATION_SOCIAL_FACEBOOK'));
				}
				$user = $user->row(1);
				$this->return_roles($user);
			}
		} catch (Exception $e) {
			throw new Exception($e->getMessage());
		}
	}
	public function load_params($params) {}
    private function check_req() {}
}

The Facebook authenticator will automatically create a new role with the role ID as the user identifier and the source authentication_service_id as AUTHENTICATION_SOCIAL_FACEBOOK or will return the role if it is already authenticated.

Note that the load_params($params) and check_req() function are overwritten and do nothing, because this is an OAuth 2.0 authentication. Username/Password authentication will have the ability to load the parameters that require checking and check them before doing authentication

PHP
public function load_params($params) {
	$this->params = $params;
	$this->check_req();
}

private function check_req() {
	$required_fields = array('username', 'password');
	foreach($required_fields as $req) {
		if(!isset($this->params[$req]) || trim($this->params[$req])==''){
			throw new Exception('Field '.$req.' is required');
		}
	}
}

So username and password can be checked if it is passed in or not.

Also, there are other functions/hook that can be used within the authenticator to manage redirection after an authentication success, they are post_authentication_hook and redirect_hook, these are automatically called in the return_roles function, but if one wishes to overwrite the redirect functionality (for eg. redirect to a different domain), they can be overwritten without problem, as the user is already authenticated via the PHP SESSION.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.