For a project I am working on, I am playing with Joomla’s authentication and user management. As expected, the mechanism is quite complex, both to understand and to modify.
First, a little explanation of what authentication is. We are all familiar with the username+password The whole mechanism is composed of a persistent state (authenticated/not authenticated), and a function to switch from one state to the other (from not authenticated to authenticated, and vice versa).
The “state†is a variable whose value is kept stored in a session – that is, a mix of client-side browser’s cookies, and server-side database tables and files. Contrary to the other procedures or parameters, a “state†is persistent among subsequent requests.
The “function†for changing the state is just a method/function that checks a series of values (such as username and password from the visitor) usually against a database table. If the result of this check is positive, the function changes the state from not authenticated to authenticated. We will also have a function for logging out, but it will be similar (and easier) than the login function.
In the end, we have:
- a state (authenticated/not authenticated)
- a state-changing function, which usually comprehends:
- a condition-check procedure for checking if the transition is allowed (usually checking username and password against a database table)
- a database table storing the parameters to check (for example, username and password)
That schema is common to the authorization procedures of all websites, whether they are run with Joomla, with another CMS or with proprietary software, but the way it is implemented really depends on the structure of the CMS.
Joomla has a component (/components/com_users), with a user controller (UsersControllerUser) responsible for the registering, reminding and resending actions, and a registration controller (UsersControllerRegistration) with the method register and activate. Looking at the above schema, the com_users component is only responsible of the latter item, the database table: it stores information about a new user in the database (information such as username and password); it retrieves those information, changes them, and saves them back into the database. It does not affect the state, nor the state-changing function.
The user controller is also able to start the authentication procedure via the login and logout methods. This is because components’ controllers are the only parts of Joomla that are callable from the outside. The login method, for example, displays a form, receives username and password values, and starts the authentication procedure via
JApplication::login($credentials, $options) (in file /libraries/joomla/application/application.php) is the real beginning of the authentication procedure. This method is called not only by UsersControllerUser, but also by the registration function to login the newly created user, and by any other component dedicated to user authentication (such as the Twitter one I am working at right now).
JApplication::login calls JAuthentication::authenticate($credentials, $options) (file /libraries/user/authentication.php). The authenticate method goes through all the registered authentication plugins (found in /plugins/authentication/*), and for each plugin it instantiates the relative class and calls the method $plugin->onUserAuthenticate($credentials, $options, $response).
The onUserAuthenticate is the real state-changing function of Joomla (or, to be precise, functions, as there is a different one for each authentication plugin).
$response is JAuthenticationResponse object carrying the plugin response. Inside of the onUserAutheticate there is the condition-check procedure, and if it turns out positive, $response->status is set to JAuthentication::STATUS_SUCCESS, and the user is then authenticated. If you want to authenticate a particular user, $response->username should be also set to a valid Joomla username (otherwise a temporary user is created).
The relevant part – that is, what you should focus on when you want to create or alter an authentication method in Joomla – is the /plugins/authentication/* directory, and specifically the onUserAuthenticate() methods.
The real change of state is a complex procedure that is performed once the STATUS_SUCCESS is returned. You can ignore it unless you have a specific interest in it. Precisely, the JApplication::login goes through all the registered user plugins (/plugins/user/*) calling the method onUserLogin(). If you had set the $response->username properly, the Joomla standard user plugin (plgUserJoomla in /plugins/user/joomla.php) creates the relative JUser instance and changes the state from not authenticated to authenticated.
After the authentication is successful, the authenticated JUser object is stored into the session (JSession) with a key ‘user’, and can be retrieved through $user = JFactory::getUser() (it returns a JUser object).
Let’s suppose you want all of your users to be able to login with a password equal to the reverse of the username (user John and password nhoJ). Your /plugin/authentication/reverse.php plugin would be:
To sum up:
- components are for putting users into database and for managing them (creating, deleting, changing passwords, etc.)
- libraries do the real session handling and plugin browsing
- plugins are for doing the actual matching username/password->database, or other type of authentication (such as social media authentication)
- if you want to build your own authentication method, you should put the logic (the state-changing function) into plgAuthenticationYOURPLUGIN:: onUserAuthenticate($credentials, $options, $response) ( into a file /plugins/authentication/*.php). Remember to register it as a valid plugin, or it won’t be executed!