DokuWiki

It's better when it's simple

User Tools

Site Tools


auth:ggauth

This is an old revision of the document!


Experimental Auth Backends

This is a package of auth backends for Dokuwiki.

AuthTypeExtendsDescription
simplebasicAbstract base class
split ( login / groups )simpleDelegates authentication to one backend (login auth), authorisation to another (groups auth)
chained ( auth1, auth2, … )simpleDelegates to the first backend in a list that responds for a given user
httpsimpleExternal authentication via PHP_AUTH_USER and PHP_AUTH_PW variables
httpbasichttpLogout support for BASIC authentication
htaccesshttpbasicFull authentication backend for htaccess style user/password files
pamsimpleExample refactored version of Michael Gorven's Pluggable Authentication Module backend

All of these are compatible with user profile updates and the User Manager plugin, as best make sense (to me).

Note dokuwiki is just a hobby for me. dokuwiki security might be critical to you. If so you should take a good look at and understand the code before letting this stuff loose on the internet, particularly as you've just downloaded it from a random internet site. I monitor the mailing list, and periodically check this page and am very happy to take feedback. Perhaps if you like this stuff it might one day make its way into the core of dokuwiki.

Grant Gardner 2008/12/16 18:55

Requirements

I only have PHP5 to test with, but should work with PHP4 (>=4.0.7).

Tested with dokuwiki-2008-05-05

Installation

Unpack http://lastweekend.com.au/ggauth.4.zip into the top level directory of your dokuwiki installation (all files are in DOKU_HOME/inc/auth)

For dokuwiki version 2010-11-07a “Anteater” (and sup ?) use http://lastweekend.com.au/ggauth.5.zip

In local.php or local.protected.php set $conf['authtype'] = <your choice of backend>

Refer to the sections below for configuration of the specific backend

Known issues

The Anteater release has implemented a logout capability, or more precisely the ability to indicate that logout is not possible, and removed the logOff capability which breaks the htaccess backend.

  • I was getting an error instead of a logout button. To correct, I went to DOKUWIKI/inc/auth and edited split.class.php (since I'm using split authentication). On line 406 I commented out “case 'logoff':” and instead added “case 'logout':”. Saved the file and reloaded my wiki. Now I can log in and out fine. This may have to be tweaked if you are using different auth methods, and I'm not positive of the long term effects of this change. — Thomas Hawkins 2010/11/25 10:27

Untested! I've made what I think are the appropriate changes, mainly to split and httpbasic. ggauth.5.zip. Feel free to try this out and report back to me — lwoggardner 2010/12/07 13:16

Works for me with Anteater release. Thank you Grant. — bug 2010/12/26 11:33

Works for me too with Anteater release. using split + chained ldap/plain. 2011/04/07 18:40


Nasty use of cleanID by the plain backend, outside of the object instance will remove “@” symbols from a user id, which is not very nice if you want to used email addresses as userids with either chained or split. (TODO: raise issue, consider security implications of deleting that code, or find some other way to do it without corrupting the global vars). The new active directory backend has some of this too, probably for good reason. Need to find out why.)

auth.php - update profile does not properly separate auth capabilities in that if your backend does not respond to both modMail and modName it will fail because one of them will be empty (TODO: raise issue with patch)


The split method does not include groups from the group auth backend when displaying the user list in the user manager, but only those delivered by the login backend. This can lead to unexpected results, as the login backend may not provide groups or it may have group editing disabled. Therefore, that a full and reliable group list can only be displayed when merging with the list delivered by the group backend.

Replacing the retrieveUsers() function in split.class.php with following code solves this issue:

function retrieveUsers($start=0,$limit=-1,$filter=null) {
  $users = $this->authForUserList()->retrieveUsers($start,$limit,$filter);
  
  foreach ($users as $name => &$user) {
    $groups_user = $this->authForGroups->getUserData($name);
    if ($groups_user !== false) {
      if ($this->mergeGroups && !empty($login_user['grps'])) {
        $user['grps'] = array_unique(array_merge($user['grps'], $groups_user['grps']));
      }
      else {
        $user['grps'] = $groups_user['grps'];
      }
    }
  }
  
  return $users;
}

The Backends

Simple

Abstract base class of all backends

It provides a getDefaultUser() method for constructing a user with a default name (the userid) and email address (user@<config value>)

An authentication only backend can be created by extending this class and implementing only the checkPass($user,$pass) method.

Many of the other user contributed backends (radius, ntlm, imap etc..) that extend plain could easily be refactored to extend simple and only provide authentication.

Assumes there is no way to test for existence of a user so every request for a specific user returns a default user. If you can test for existence, then you are likely overriding getUserData() anyway.

Configuration

 
$conf['defaultgroup'] = 'somegroup'; # every user will be a member of this group
$conf['auth']['maildomain'] = 'localhost'; # default user email will be set to <user>@defaultDomain
$conf['auth']['debug'] = false; # debugging
$conf['auth']['debug_hidden'] = false; #hide debug in html output @see dbg() in infoutils.php
$conf['auth']['debug_to_file'] = false; #also debug to file @see dbglog in infoutils.php

Split

Split authentication/authorisation backend, delegates authentication to one backend (login auth), authorisation to another (groups auth)

Extends: simple

Configuration

$conf['auth']['split']['login_auth'] = 'ldap'    # the auth backend for authentication
$conf['auth']['split']['groups_auth'] = 'plain'  # the auth backend that supplies groups
$conf['auth']['split']['merge_groups'] = false   # should groups from login auth also be included
$conf['auth']['split']['use_login_auth_for_users'] = false # Should login auth be used for supplying the list of users for usermanager
$conf['auth']['split']['use_login_auth_for_name'] = false # Should login auth supply user name, or only used if groups auth provides an empty name
$conf['auth']['split']['use_login_auth_for_mail'] = false # Should login auth supply email address, or only used if groups auth provides empty email.

If auth login supports the 'external' method and does not implement checkPass then $conf['profileconfirm'] should be false or the password check will fail.

See also configuration of simple

User Manager Integration

List of users comes from groups auth unless $conf['auth']['split']['use_login_auth_for_users'] = true;

Create/modify/delete are delegated to both backends if they are capable. It is possible to modify a user that exists in only one backend in which case it will be created in the other. Obviously this is not transactional so you may find difficulties if errors occur on one but not the other.

It is also possible that the authoritative backend for password, name, or email does not accept updates but the non-authoritative one does, the updates will be successful but you won't see the result.

Chained

Extends: simple

Delegates to the first backend in a list that responds to getUserData() with a non empty user.

Alternatively it can be configured to attempt authentication (user/pass) on each link in the chain until one passes. This is useful in the case of a backend that returns a default user for every request (eg pam, below; and sometimes “ldap”, see note), but will likely be slow for users that exist in deeper parts of the chain.

Since version 0.4, now supports “external” delegates (eg the Shibboleth backend). If any delegate in the chain supports “external” and is satisfied, then that backend will be used for the current user.

The *Profile* option is made available depending on the capabilities of the backend that represents the current user.

One of the backends can be specified as the one to use with the User Manager plugin.

Configuration

$conf['auth']['chained']['authtypes'] = # list of authtypes, eg 'ldap,plain'
$conf['auth']['chained']['usermanager_authtype'] = null; # which of the authtypes should be checked for usermanager capabilities
$conf['auth']['chained']['find_auth_by_password'] = false; # Follow the chain in the checkpass method.
Using "ldap" with chained

If “%{user}” appears in the “usertree” option, the ldap backend cannot find users except when checking the password. In this case “find_auth_by_password” must be set to true for chained to function properly. Alternatively change your ldap configuration to find users by searching, either anonymously or using the credentials supplied in the “binddn” and “bindpw” options.

HTTP

Extends: simple

Supports external authentication via PHP_AUTH_USER and PHP_AUTH_PW as supplied via your webserver.

Note that the following config options should be set, as these features don't play nice with external authentication.

$conf['openregister']= 0; 
$conf['resendpasswd']= 0; 

HTTPBasic

Extends: http

This backend attempts to provide a logoff function for BASIC authentication.

It does not send the WWW:Authenticate headers at login, you need to configure your webserver to do that, eg via .htaccess

Configuration

 $conf['auth']['httpbasic']['realm'] = 'dokuwiki' # must match the realm used for BASIC auth of your webserver.
 $conf['auth']['httpbasic']['logout'] = '' # custom logout message (may not be displayed in all browsers)

NOTE

HTAccess

Use htaccess formatted password and groups files common to other web applications.

Extends: httpbasic

Finds and reads a ”.htaccess” file then uses the AuthUserFile and AuthGroupFile directives to point to the list of users and groups respectively. A 3rd, non-standard, file “htuser” is used to store the fullname and the email address required by dokuwiki.

Configuration

 $conf['authtype'] = 'htaccess';   
 #
 # name of .htaccess file, must exist if absolute, if relative will search for this file up to the document root.
 $conf['auth']['htaccess']['htaccess'] = '.htaccess'; 
 #
 # name of file to store names and emails for each user. if relative assumed same directory as "AuthUserFile" directive.
 $conf['auth']['htaccess']['htuser'] = 'htuser';

Also refer to httpbasic configuration.

A typical .htaccess file would live in the dokuwiki root directory or somewhere further up the path and look something like…

AuthName Dokuwiki
AuthUserFile /home/unison/dokuwiki/htpasswd
AuthGroupFile /home/unison/dokuwiki/htgroups

# Use Basic authentication
AuthType Basic
<Limit GET POST>
satisfy all
require valid-user
</Limit>

AuthUserFile must point to an existing (possibly empty) file.

AuthGroupFile is optional, but omitting it will only make sense if you set $conf['defaultgroup'] and set default acl to allow something on that group.

These files must be writable by your webserver user if you want to add new users, allow users to change passwords etc…

Although this backend extends httpbasic and will work effectively behind BASIC authentication, it works best with dokuwiki's normal login page by setting $conf['auth']['htaccess']['htaccess'] to point to a file containing the AuthUserfile and AuthGroupFile directives to point at files that are used for other applications.

You will lose single sign-on capability between applications but things like openregister and resendpasswd will work as dokuwiki intends.

PAM

Extends: simple

Refactored version of Pluggable Authentication Module backend to extend simple and implement change password.

The chpass method is experimental and has not been tested successfully because my pam-unix configuration requires the webserver to run as root to change passwords of other users.

Mock

Extends: simple

Implements an “external” backend that looks at the http header “X-MOCK-DW-AUTH” for the user id to use.

Obviously only useful for testing (eg with the Modify Headers firefox addon).

Configuration

$conf['authtype'] = 'pam';
$conf['auth']['pam']['chpass'] = false; #if enabled and module supports chpass, then user will be able to modify their own password

Use Cases

Which backend is right for me? Here are some scenarios to help you out.

Feel free to make a note about your working combination under the relevant section.

Existing external passwords, all users in a default group

Soln: Extend simple, implement checkPassword($user,$pass)

See pam as an example.

Existing external passwords (eg RADIUS), more complex access control with multiple groups

Soln: split (radius/plain)

ie, Implement RADIUS auth by extending simple as above, and use that backend for logins, and use plain or mysql to provide the groups.

Many of the user contributed backends (eg Radius, PAM, NTLM, imap) (TODO: links) extend plain and override the password check. They could easily be refactored to work in this fashion, thus allowing the use of mysql or something else to store groups.

Corporate LDAP server for users, mail and passwords, but manage group outside of LDAP

Typically your dokuwiki install is in some dingy corner of the corporate and your dokuwiki admin isn't allowed to play with groups in the Corporate LDAP.

Soln: split (ldap / plain) and configured to get names/email addresses from the ldap backend.

Manage internal and external users separately

eg. You have a large user base in the campus ldap and some additional external users that you want to give access to a subset of your dokuwiki

Soln: chained ( ldap, plain ).

Internal users authenticated via LDAP, allow other external users and manage groups across both

This is getting fun :-)

Soln: split ( chained ( ldap, plain ) / plain )

ie you can use chained as the login delegate for split. Two instances of plain will be created but they both point at the same configuration. Profile updates would be applied twice.

Note that this configuration has not been tested.

Example: AD for login, Plain for Groups and Other Users

This is the configuration we use for our internal Dokuwiki server (since we sometimes want to bring in outside users, and they won't create AD accounts for it. Any AD user will have read abilities, and I configure the groups within Dokuwiki for write permissions*. Here is my config which I placed in local.protected.php:

<?php
/**
 * This is the advanced authorization settings
 */
$conf['authtype'] = 'split';

$conf['auth']['split']['login_auth'] = 'chained';
$conf['auth']['split']['groups_auth'] = 'plain';
$conf['auth']['split']['merge_groups'] = false;
$conf['auth']['split']['use_login_auth_for_users'] = false;
$conf['auth']['split']['use_login_auth_for_name'] = false;
$conf['auth']['split']['use_login_auth_for_mail'] = false;

$conf['auth']['chained']['authtypes'] = 'ldap,plain';
$conf['auth']['chained']['usermanager_authtype'] = null;
$conf['auth']['chained']['find_auth_by_password'] = false;

$conf['auth']['ldap']['server'] = '{AD Server Name}';
$conf['auth']['ldap']['binddn'] = '{AD Server Account}';
$conf['auth']['ldap']['bindpw'] = '{AD Server Password}';
$conf['auth']['ldap']['usertree'] = '{User Tree}'; //cn=something,dc=somethingelse,dc=somethingelse2,etc
$conf['auth']['ldap']['userfilter'] = '(samaccountname=%{user})';
$conf['auth']['ldap']['mapping']['name'] = 'displayname';
$conf['auth']['ldap']['referrals'] = 0;
$conf['auth']['ldap']['version'] = 3;
//$conf['auth']['ldap']['debug'] = 1; //Might come in handy.

* One issue with this is that you cannot use the user manager to create accounts, and assign them to groups. You will need to either change the backend and disassociate it with AD when configuring accounts, or edit the users.auth.php file and manually add the accounts. Once the accounts are added, you can edit them within DW and assign them to groups. I've tested this with both 2008-05-05 and 2009-02-14. — Thomas Hawkins 2009/02/23

Webserver configured for BASIC authentication, no groups

Soln: httpbasic

Webserver configured for BASIC authentication, with groups

Soln: split ( httpbasic / plain )

Other applications secured via htaccess password and groups files, re-use for dokuwiki

Soln: htaccess

External authentication (shibboleth) and internal authentication (local account)

Soln: chained ( shib, plain ).

Notes : I used this Shibboleth backend with the chained module v.0.4. Now, I can be logged either with shibboleth or with the plain authentication method.
You can add a shibboleth account and a plain account in the same group.

Benjamin SECLIER 2009/10/29 09:05

auth/ggauth.1302194792.txt.gz · Last modified: 2011-04-07 18:46 by 194.167.226.194

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