if(($ACT == 'edit' || $ACT == 'preview') && $INFO['editable']){ ?> } else { ?> } ?>
Towards oAuth support for DokuWiki.
The use-case are manifold: oAuth allows to perform secure authenticated requests (eg. over HTTP) without requiring a user to disclose credentials. Dokuwiki can make use of this for instance with XML-RPC, dokupubsub, batch media-upload (client-applications) or even feed subscription, etc. Simply: any DokuWiki request.
You may still want to run a HTTPS server to authenticate users by plaintext-password against DokuWiki or require digest-auth (which still requires the user to know the password). Combined with openID, oAuth is a prerequisite for distributed client-server and server-to-server communication such as feed/media aggregation or DokuWiki-farms over insecure connections.
Patch DokuWiki's inc/auth.php
to provide a trigger that allows to hook into the authentication mechanism.
--- a/inc/auth.php +++ b/inc/auth.php @@ -72,7 +72,13 @@ // external trust mechanism in place $auth->trustExternal($_REQUEST['u'],$_REQUEST['p'],$_REQUEST['r']); }else{ - auth_login($_REQUEST['u'],$_REQUEST['p'],$_REQUEST['r']); + $evt = new Doku_Event('ACTION_ON_AUTH',$ACT); + $evt->advise_before(); + if(empty($_SERVER['REMOTE_USER'])) { + auth_login($_REQUEST['u'],$_REQUEST['p'],$_REQUEST['r']); + } + $evt->advise_after(); + unset($evt); } }
Example action-plugin to provide authentication on a per HTTP-request basis:
if(!defined('DOKU_INC')) die(); class action_plugin_oauth extends DokuWiki_Action_Plugin { function register(&$contr){ $contr->register_hook('ACTION_ON_AUTH', 'BEFORE', $this, 'handle_act_authhook'); $contr->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_act_preprocess'); } function handle_act_authhook(&$event, $param){ if (is_array($_REQUEST['do']) && !empty($_REQUEST['do']['oauth'])) return; // skip requests to oauth-API itself if (!empty($_REQUEST['oauth_signature'])) { // verify signature // check consumer and access token // -> bail out if signature mismatch // -> set username for this session // dokuwiki - set user $user='root'; $_SERVER['REMOTE_USER'] = $user; global $USERINFO; global $auth; $USERINFO = $auth->getUserData($user); if (!is_array($USERINFO)) { $_SERVER['REMOTE_USER'] = ""; // or bail out.. } } } function handle_act_preprocess(&$event, $param){ $handled=false; if (!empty($event->data['oauth'])) { // ... // token-exchange, admin, etc. // } if ($handled) { $event->stopPropagation(); $event->preventDefault(); $event->data="show"; } } } //Setup VIM: ex: et sw=4 ts=4 enc=utf-8 :
Discussion
Adding the ACTION_ON_AUTH
event to existing events does not seem to be too far out; however it raises a some concerns:
inc/auth/*.php
structure.
The first is not really true, any plugin can be used to perform malicious actions; it's just that ACTION_ON_AUTH
should never be used carelessly. This ties into the second issue: pay strict attention to optimize performance of the callback handler - On a wiki with ACLs those will be called for each request!
Last but not least: oAuth is not a DokuWiki authentication backend, it uses the getUserData()
from the backend. Instead of adding a hook, the auth-backends could be nested: oAuth could wrap the default auth-backend overriding the checkPass()
function. Adding an Event seems to be a much cleaner way to implement this.
The plugin implements an oAuth-Service Provider consisting of several parts:
checkPass()
and authenticates a DokuWiki-user on the fly.None needed. There's a few Options in Configuration Settings most of which are related to debugging or development.
After installing the Plugin, visit http://example.org/doku.php?do=oauth
to administrate tokens or simply run the example script on the next page which
adds a test consumer for you.
The OAuthDataStore is kept in DOKU_CONF/oauth.inidb
as dba.ini text data; the config-folder (or at least latter file) needs to be writable for the web-sever.
Note: Apache rewrite-rules modify the base-string! (This is to be fixed or worked-around) The query-parameters and URL must not be modified before they are passed to the PHP script (using DirectoryIndex doku.php
works, redirecting from index.php does not.) - This is a minor issue since in general oAuth requests always use a full absolute URL ending with /doku.php
(or /lib/lib/exe/xmlrpc.php
) to access the DokuWiki API.
ToDo
helper.php
)
You can access the DokuWiki OAuth API by making requests to doku.php?do[oauth]=XXX
or simply by making any request adding the oauth_signature
request-parameter.
Visit ?do=oauth
for the oauth plugin information page. For test-requests see dokuoauth_examples.