Authentication in Harmoni is handled by Harmoni's implementation of the Authentication OSID. This implementation makes use of several other agent-management systems, namely: TokenCollector, AuthN Methods, and Agent-Token Mapping. The AuthNMethodManager and its various AuthNMethods are responcible for Authenticating user-passed tokens against some data-store, as well as specifying which AuthNToken class and TokenCollector should be used when interfacing with them. The TokenCollector's only resposibility is to request and retrieve user-passed tokens. The Agent-TokenMappingManager is responcible for maintaining mappings between AgentIds and the tokens that they correspond to in the various authentication systems.
Below is a sample configuration script that uses two authentication methods, a local database, and an LDAP server.
...
// :: Set up the DatabaseManager ::
$configuration =& new ConfigurationProperties;
Services::startManagerAsService("DatabaseManager", $context, $configuration);
//Set up the database connection
$databaseManager =& Services::getService("DatabaseManager");
$dbName = "adam_concerto";
$dbID = $databaseManager->addDatabase( new MySQLDatabase("localhost", $dbName,"test","*****") );
$databaseManager->pConnect($dbID);
unset($databaseManager); // done with that for now
// :: Set up the IdManager as this is required for the ID service ::
$configuration =& new ConfigurationProperties;
$configuration->addProperty('database_index', $dbID);
$configuration->addProperty('database_name', $dbName);
Services::startManagerAsService("IdManager", $context, $configuration);
// :: Set up the AgentManager ::
$configuration =& new ConfigurationProperties;
$configuration->addProperty('database_index', $dbID);
$configuration->addProperty('database_name', $dbName);
Services::startManagerAsService("AgentManager", $context, $configuration);
// :: Start the AuthenticationManager OSID Impl.
$configuration =& new ConfigurationProperties;
$tokenCollectors = array(
// serialize(new Type ("Authentication", "Middlebury College", "Concerto DB"))
// => new BasicFormNamePassTokenCollector,
serialize(new Type ("Authentication", "Middlebury College", "Concerto DB"))
=> new FormActionNamePassTokenCollector(MYURL."/auth/username_password_form/".implode("/",$harmoni->pathInfoParts)),
);
$configuration->addProperty('token_collectors', $tokenCollectors);
Services::startManagerAsService("AuthenticationManager", $context, $configuration);
// :: Start and configure the AuthenticationMethodManager
$configuration =& new ConfigurationProperties;
// set up a Database Authentication Method
require_once(HARMONI."/oki2/agentmanagement/AuthNMethods/SQLDatabaseAuthNMethod.class.php");
require_once(HARMONI."/oki2/agentmanagement/AuthNMethods/SQLDatabaseMD5UsernamePasswordAuthNTokens.class.php");
$dbAuthType =& new Type ("Authentication", "Middlebury College", "Concerto DB");
$dbMethodConfiguration =& new ConfigurationProperties;
$dbMethodConfiguration->addProperty('tokens_class', $arg0 = 'SQLDatabaseMD5UsernamePasswordAuthNTokens');
$dbMethodConfiguration->addProperty('database_id', $dbID);
$dbMethodConfiguration->addProperty('authentication_table', $arg2 = 'auth_db_user');
$dbMethodConfiguration->addProperty('username_field', $arg3 = 'username');
$dbMethodConfiguration->addProperty('password_field', $arg4 = 'password');
$propertiesFields = array(
'username' => 'username',
'name'=> 'display_name',
);
$dbMethodConfiguration->addProperty('properties_fields', $propertiesFields);
$dbAuthNMethod =& new SQLDatabaseAuthNMethod;
$dbAuthNMethod->assignConfiguration($dbMethodConfiguration);
unset($arg0, $arg1, $arg2, $arg3, $arg4, $propertiesFields, $dbMethodConfiguration);
$configuration->addProperty($dbAuthType, $dbAuthNMethod);
// set up LDAPAuthentication Method
require_once(HARMONI."/oki2/agentmanagement/AuthNMethods/LDAPAuthNMethod.class.php");
require_once(HARMONI."/oki2/agentmanagement/AuthNMethods/LDAPAuthNTokens.class.php");
$ldapAuthType =& new Type ("Authentication", "Middlebury College", "Middlebury LDAP");
$ldapConfiguration =& new ConfigurationProperties;
$ldapConfiguration->addProperty('tokens_class', $arg0 = 'LDAPAuthNTokens');
$ldapConfiguration->addProperty("LDAPHost", $arg1 = "ad.middlebury.edu");
$ldapConfiguration->addProperty("baseDN", $arg2 = "cn=users,dc=middlebury,dc=edu");
$ldapConfiguration->addProperty("bindDN", $arg3 = "juser");
$ldapConfiguration->addProperty("bindDNPassword", $arg4 = "*******");
$propertiesFields = array (
'username' => 'samaccountname',
'name' => 'displayname',
'first name' => 'givenname',
'last name' => 'sn',
'department' => 'department',
'email' => 'mail',
);
$ldapConfiguration->addProperty('properties_fields', $propertiesFields);
$loginFields = array (
'samaccountname',
'mail',
'cn',
);
$ldapConfiguration->addProperty('login_fields', $loginFields);
$ldapAuthNMethod =& new LDAPAuthNMethod;
$ldapAuthNMethod->assignConfiguration($ldapConfiguration);
unset($arg0, $arg1, $arg2, $arg3, $arg4, $propertiesFields, $loginFields, $ldapConfiguration);
$configuration->addProperty($ldapAuthType, $ldapAuthNMethod);
Services::startManagerAsService("AuthNMethodManager", $context, $configuration);
// :: Agent-Token Mapping Manager ::
$configuration =& new ConfigurationProperties;
$configuration->addProperty('database_id', $dbID);
Services::startManagerAsService("AgentTokenMappingManager", $context, $configuration);
...
To initiate the authentication sequence, call the AuthenticationManager::authenticatUser($authenticationType) method. Below is an example of this usage from Polyphony's auth.login_type action. This polyphony action can simply be linked to from your application to provide authentication handling.
<?php
/**
* @package polyphony.modules.authentication
*/
$isAuthenticated = FALSE;
$authN =& Services::getService("AuthN");
$typeString = urldecode($harmoni->pathInfoParts[2]);
$typeParts = explode("::", $typeString);
$authType = new Type ($typeParts[0],$typeParts[1],$typeParts[2]);
$currentPathInfo = array_slice($harmoni->pathInfoParts, 3);
$returnHeader = "Location: ".MYURL."/".implode("/",$currentPathInfo);
if ($authN->isUserAuthenticated($authType)) {
header($returnHeader);
}
// If we aren't authenticated, try to authenticate.
else {
// Try authenticating with this type
$authN->authenticateUser($authType);
// If they are authenticated, return.
if ($authN->isUserAuthenticated($authType)) {
header($returnHeader);
}
// Otherwise, print our our failed-login screen:
else {
// Get the Layout compontents. See core/modules/moduleStructure.txt
// for more info.
$harmoni->ActionHandler->execute("window", "screen");
$mainScreen =& $harmoni->getAttachedData('mainScreen');
$statusBar =& $harmoni->getAttachedData('statusBar');
$centerPane =& $harmoni->getAttachedData('centerPane');
// Set our textdomain
$defaultTextDomain = textdomain();
textdomain("polyphony");
ob_start();
print "<p>";
print _("Log in failed.");
print "\n<br /><a href='".MYURL."/".implode("/",$currentPathInfo)."'>";
print _("Go Back");
print "</a> ";
print _(" or ");
print "\n<a href='".MYURL."/auth/login_type/".$harmoni->pathInfoParts[2]."/".implode("/",$currentPathInfo)."'>";
print _("Try Again.");
print "</p>";
$introText =& new Block(ob_get_contents(), 2);
ob_end_clean();
$centerPane->add($introText, null, null, CENTER, CENTER);
// go back to the default text domain
textdomain($defaultTextDomain);
// return the main layout.
return $mainScreen;
}
}
AuthZ provides an implementation of a hierarchical authorization system. Polyphony's authorization module provides tools for managing authorizations.
// :: Set up the DatabaseManager ::
$configuration =& new ConfigurationProperties;
Services::startManagerAsService("DatabaseManager", $context, $configuration);
//Set up the database connection
$databaseManager =& Services::getService("DatabaseManager");
$dbName = "adam_concerto";
$dbID = $databaseManager->addDatabase( new MySQLDatabase("localhost", $dbName,"test","*****") );
$databaseManager->pConnect($dbID);
unset($databaseManager); // done with that for now
// :: Set up the Authorization System ::
$configuration =& new ConfigurationProperties;
$configuration->addProperty('database_index', $dbID);
$configuration->addProperty('database_name', $dbName);
Services::startManagerAsService("AuthorizationManager", $context, $configuration);
When you application is first installed/configured you will most likely need to define some functions which you will later check to see if users are authorized to do.
...
$authZManager =& Services::getService("AuthorizationManager");
$idManager =& Services::getService("IdManager");
$qualifierHierarchyId =& $hierarchyId; // Id from above
$type =& new Type ("Authorization", "Concerto", "Editing", "Functions for editing.");
$id =& $idManager->createId();
$function =& $authZManager->createFunction($id, "Add Children", "Add children to this qualifier.", $type, $qualifierHierarchyId);
...
Inside your actions, isUserAuthorized() is the only method needed to check for appropriate authorization for the currently authenticated Agent(s). You must however, know the id of the Function that you wish to check authorizations for, as well as the Id of the node in the qualifier hierarchy at which you wish to check authorization.
...
// Check for our authorization function definitions
if (!defined("AZ_ADD_CHILDREN"))
throwError(new Error("You must define an id for AZ_ADD_CHILDREN", "concerto.collection", true));
// Check that the user can create a collection here.
$authZ =& Services::getService("AuthZ");
$idManager =& Services::getService("Id");
if (!$authZ->isUserAuthorized($idManager->getId(AZ_ADD_CHILDREN), $node->getId())) {
print _("You are not authorized to create a <em>Collection</em>.");
return;
}
// Continue with the action if the user is authorized.
...
The IdManager provides services for creating unique Ids and building Id objects.