DokuWiki

It's better when it's simple

User Tools

Site Tools


devel:auth_plugins

Authentication Plugins

DokuWiki's authentication system is highly modular and can, generally speaking, authenticate using anything that is accessible from PHP. Check the list of Auth Plugins to see what is already available. Auth Plugins can be installed via the Extension Manager.

Authentication plugins provide multiple tasks:

  1. authenticate the current user, eg. check some password, trust a cookie or similar
  2. provide user information on any user, eg. get the name, email address, and group memberships
  3. provide mechanisms to manage users, eg. create new users, change profile data

Synopsis

Please refer to plugins and plugin file structure for general info for plugin development. Best use the dev plugin to get started.

Your new class needs to follow the general naming scheme for plugins and inherit from dokuwiki\Extension\AuthPlugin.

Eg. for a plugin example, the class name would be auth_plugin_example defined in lib/plugins/example/auth.php.

Below, the most important methods when writing an auth plugin are described. Refer to common plugin functions for inherited functions available to all plugins and check your IDE for additional possible overrides.

Initialization and Capabilities

Your plugin needs to signal that it is ready to use to DokuWiki's authentication sub system.

This is done in the plugin's constructor. You can use it check that configuration is complete, database connections work, etc. If everything is okay, you need to set the $success property to true.

You also need to signal what functionality your plugin provides. For example with some backends it might not be possible to change user names while others have no way to log out after logging in. This is done by setting the different flags in the $cando property. The more flags you enable here, the more methods you need to implement as described below.

public function __construct()
{
    parent::__construct();
 
    $this->cando['modName'] = true;
    $this->cando['modMail'] = true;
 
    $this->success = true;
}

Here is a list of keys in $cando and their meaning:

  • addUser – can Users be created?
  • delUser – can Users be deleted?
  • modLogin – can login names be changed?
  • modPass – can passwords be changed?
  • modName – can real names be changed?
  • modMail – can emails be changed?
  • modGroups – can groups be changed?
  • getUsers – can a (filtered) list of users be retrieved?
  • getUserCount – can the number of users be retrieved?
  • getGroups – can a list of available groups be retrieved?
  • external – does the module do external auth checking?
  • logout – can the user logout again? (eg. not possible with HTTP auth)

Authentication

There are two distinct ways of how your authentication plugin can authenticate the current user:

  1. Let DokuWiki do most of the work and only do password checking in your plugin
  2. Implement the authentication yourself, for example when trusting a 3rd party cookie

checkPass

The first method is the default. It requires you to implement the checkPass() method. This function need to check if the given userid $user exists and the given plaintext password $pass is correct.

public function checkPass($user, $pass)
{
    // obviously implement a real check here
    if($user == 'andi' && $pass='secret') {
        return true;
    }
    return false;
}

trustExternal

The second option is to implement the trustExternal() method. Be sure to also enable the trustExternal flag in the canDo array.

The trustExternal() method completely replaces the default auth_login() function from inc/auth.php, so might read a bit into its sources.

The method needs to set a few DokuWiki internal variables to create a logged in state. Namely $USERINFO, $_SERVER['REMOTE_USER'] and $_SESSION[DOKU_COOKIE]['auth'] infos.

The implementation depends very much on your backend, here are some often used parts indicated as example. Look also for other implementations, when it doesn't fit your requirements.

function trustExternal($user, $pass, $sticky=false) {
    global $USERINFO;
    global $lang;
 
    // someone used the login form
    if(!empty($user)){
        //situation: there are user credentials, lets check them
        if( ...try to authenticate against your backend...)
 
            // here you can handle additional post login actions 
            // for your backend
 
        }else{
            //invalid credentials - log off
            msg($lang['badlogin'],-1);
            auth_logoff(); // needs implementation of logOff() method
            return false;
        }
    }
 
    //situation: no login form used or logged in successful 
 
 
    // check where if there is a logged in user e.g from session,
    // $_SERVER or what your auth backend supplies...
 
    if( ...check here if there is a logged in user...) {
 
        $USERINFO['name'] = string
        $USERINFO['mail'] = string
        $USERINFO['grps'] = array()
 
        $_SERVER['REMOTE_USER']                = $user; //userid
        $_SESSION[DOKU_COOKIE]['auth']['user'] = $user; //userid
        $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
 
        return true;
    }else{
        //when needed, logoff explicitly.
    }

In theory you can create an auth plugin that only implements trustExternal however, it is strongly recommended to have getUserData() so DokuWiki can display your users nicely and logoff() to permit DokuWiki to communicate the logoff to your backend.

Get User Information

getUserData

DokuWiki will need to query user information for the currently logged in user (if not supplied in trustExternal) but also for other users. The latter happens for example when Email Subscriptions are handled or full user names are to be displayed.

User information is requested from your plugin via the getUserData() method.

The method should return an array with at least the full name and email address for the given $user. If $requireGroups is true, the user's groups should be returned as well. Return false if the given user can't be found.

public function getUserData($user, $requireGroups = true)
{
    // obviously implement real user data retrieval here
    if ($user == 'andi') {
        return [
           'name' => 'Andreas Gohr',
           'mail' => 'andi@splitbrain.org',
           'grps' => ['user', 'admin']
        ];
    }
 
    return false;
}

retrieveUsers

optional, set getUsers capability

The retrieveUsers() method is used to retrieve a list of users matching a given criteria. It is used for example in the usermanager Plugin.

FIXME explain filter syntax

getUserCount

optional, set getUserCount capability

The getUserCount method returns the number of users matching certain filter criteria. Used for pagination in the usermanager Plugin. (Needed when retrieveUsers() is implemented)

retrieveGroups

optional, set getGroups capability

The retrieveGroups method returns a list of all available groups.

User Management

createUser

optional, set addUSer capability

The createUser() method creates a user with the provided data. Returns false, when user already exists, null on error and true when successful.

modifyUser

optional, set modLogin, modPass, modName, modMail, modGroups capabilities

The modifyUser() method modifies a user's data. You can expect to only receive data as per set capabilities.

deleteUsers

optional, set delUser capability

The deleteUsers() method deletes one or more users.

addGroup

optional

The addGroup() method creates a new group. This only needs to be implemented if a group needs to be created before users can be assigned to it.

Utility Methods

logOff

optional, set logout capability

The logOff() method is run in addition to the usual logoff. It is useful with trustExternal() to initiate actions for the external backend e.g. use it to clear cookies or similar actions.

isCaseSensitive

When your backend is caseinsensitive, implement isCaseSensitive() and return false.

cleanUser

optional

The cleanUser() method is applied when a username is given to and returned from the backend. Can be used to enforce username restrictions.

cleanGroup

optional

The cleanGroup() method is applied when a group name is given to and returned from the backend. Can be used to enforce group name restrictions.

Groupnames are passed without a leading @ here.

useSessionCache

optional

DokuWiki caches user info for a timespan. The useSessionCache() method can be used to influence the expiration of this caching.

Notes

Start session customization

Dokuwiki starts (in inc/init.php) a session prior to using the authentication plugin. If your framework uses specific session settings, you can define before your own settings in the file conf/local.protected.php. You need to create it when non-existing. In this conf/local.protected.php you can supply one or more of these defines:

  • DOKU_SESSION_NAME
  • DOKU_SESSION_LIFETIME
  • DOKU_SESSION_PATH
  • DOKU_SESSION_DOMAIN

The defines correspond to the arguments of session_set_cookie_params(), please refer to its docs for more details. To use SSL for your cookies, you enable the securecookie configuration setting.

conf/local.protected.php
//settings specific for use of the ... authentication plugin
define ('DOKU_SESSION_NAME', "YOURSESSIONNAME");
define ('DOKU_SESSION_LIFETIME', 0);
//etc...
 
//a custom session path
$sessiepath = fullpath(dirname(__FILE__) . '/../../') . '/session';
session_save_path($sessiepath);

Further reading

devel/auth_plugins.txt · Last modified: 2023-09-19 10:50 by andi

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki