Last active
February 4, 2021 00:45
-
-
Save dstar4138/754c384d086d0b07ba3b072acc8f3957 to your computer and use it in GitHub Desktop.
Authelia/Traefik ForwardAuth DokuWiki Auth Plugin.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* ForwardAuth DokuWiki Auth Plugin. | |
* | |
* @licence Public Domain, use how you wish, I don't caare. | |
* @author Alexander Dean-Kennedy | |
* @version 0.0.1 | |
*/ | |
// must be run within Dokuwiki | |
if(!defined('DOKU_INC')) die(); | |
/** | |
* Provides support for using ForwardAuth middlewares in reverse | |
* proxies for providing authentication to DokuWiki docker containers. | |
* | |
* NOTE: This is an extremely simple implementation that only focuses | |
* on looking-up HTTP Headers and does not support logout or even | |
* header-validation. | |
* | |
* USAGE: Configure via conf/local.php like so: | |
* | |
* $conf['authtype'] = "forwardauth"; | |
* $conf['plugin']['forwardauth']['userHeader'] = 'Remote-User'; | |
* | |
* // Optionally, you can also provide header names for the following: | |
* $conf['plugin']['forwardauth']['nameHeader'] = 'Remote-Name'; | |
* $conf['plugin']['forwardauth']['mailHeader'] = 'Remote-Email'; | |
* $conf['plugin']['forwardauth']['groupsHeader'] = 'Remote-Groups'; | |
* | |
* By default, if no value is provided for the name, we will default to | |
* the value provided by 'userHeader'. Thus setting both the User's | |
* Name and the username to the value of 'userHeader'. | |
* | |
* If no headers are provided, we default to the header names used by | |
* Authelia, as it is what I use. Referenced here: | |
* https://github.com/authelia/authelia/blob/ | |
* 7c6a86882f93515a148cadcce8eccd77c3f24433 | |
* /internal/handlers/const.go#L20-L23 | |
**/ | |
class auth_plugin_forwardauth extends DokuWiki_Auth_Plugin | |
{ | |
// Defaults for Authelia. | |
const USER_HEADER = "Remote-User"; | |
const NAME_HEADER = "Remote-Name"; | |
const MAIL_HEADER = "Remote-Mail"; | |
const GRPS_HEADER = "Remote-Groups"; | |
public function __construct() | |
{ | |
parent::__construct(); | |
$this->cando['external'] = true; // Assumes redirect already happened. | |
$this->cando['logout'] = false; // Logout happens elsewhere. | |
} | |
public function trustExternal($user, $pass, $sticky = false) { | |
// We assume $user is ALWAYS nil and overwrite with header value. | |
$data = $this->getUserData($user); | |
if ($data) { | |
return $this->fillGlobals($data); | |
} | |
return false; | |
} | |
private function fillGlobals($data) { | |
global $USERINFO; | |
$USERINFO['name'] = $data['user']; | |
$USERINFO['mail'] = $data['mail']; | |
$USERINFO['grps'] = $data['groups']; | |
$_SERVER['REMOTE_USER'] = $data['user']; | |
$_SESSION[DOKU_COOKIE]['auth']['user'] = $data['user']; | |
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; | |
return true; | |
} | |
public function getUserData($user, $requireGroups = true) | |
{ | |
// If no user is provided, no auth was done. Admin will | |
// need to fix their ForwardAuth in the reverse proxy. | |
// For example, setting the ForwardAuth middleware. | |
// I do not believe there is a course of action we can | |
// perform here as we don't know the middleware path. | |
$user = $this->getAuthUser(); | |
if (empty($user)) { return false; } | |
$data = array(); | |
$data['user'] = $user; | |
$data['name'] = $this->getAuthName(); | |
$data['mail'] = $this->getAuthMail(); | |
$data['groups'] = $this->getAuthGroups(); | |
return $data; | |
} | |
/* Extract header values from HTTP Request. */ | |
private function getAuthUser() { | |
return sane_lookup($this->getAuthUserHeader()); | |
} | |
private function getAuthMail() { | |
return sane_lookup($this->getAuthMailHeader()); | |
} | |
private function getAuthName() { | |
$name = sane_lookup($this->getAuthNameHeader()); | |
if (empty($name)) { return $this->getAuthUser(); } | |
return $name; | |
} | |
private function getAuthGroups() { | |
$groups = sane_lookup($this->getAuthGroupsHeader()); | |
return explode(',', $groups); | |
} | |
/* Generate PHP HTTP Header names from Config values. */ | |
private function getAuthUserHeader() { | |
return header_to_php_name( | |
plugin_conf('userHeader', self::USER_HEADER) | |
); | |
} | |
private function getAuthNameHeader() { | |
return header_to_php_name( | |
plugin_conf('nameHeader', self::NAME_HEADER) | |
); | |
} | |
private function getAuthMailHeader() { | |
return header_to_php_name( | |
plugin_conf('mailHeader', self::MAIL_HEADER) | |
); | |
} | |
private function getAuthGroupsHeader() { | |
return header_to_php_name( | |
plugin_conf('groupsHeader', self::GRPS_HEADER) | |
); | |
} | |
} | |
function plugin_conf($name, $default="") { | |
global $conf; | |
if (!array_key_exists('plugin', $conf)) { return $default; } | |
if (!array_key_exists('forwardauth', $conf['plugin'])) { return $default; } | |
if (!array_key_exists($name, $conf['plugin']['forwardauth'])) { return $default; } | |
return $conf['plugin']['forwardauth'][$name]; | |
} | |
function sane_lookup($header) { | |
// Simplify header lookup by making sure it is set. | |
return ($header === '') ? "" : $_SERVER[$header]; | |
} | |
function header_to_php_name($header) { | |
// Headers are all uppercase, and all '-' must be underscores. | |
return ($header === '') ? "" : "HTTP_" . strtoupper(str_replace('-', '_', $header)); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: '3.7' | |
networks: | |
traefik: | |
external: | |
name: traefik | |
# Assumes authelia is already installed/running as a middleware in traefik | |
services: | |
dokuwiki: | |
image: 'docker.io/bitnami/dokuwiki:20200729-debian-10' | |
volumes: [ '/home/docker/data/dokuwiki:/bitnami/dokuwiki' ] | |
networks: [ traefik ] | |
restart: unless-stopped | |
environment: | |
DOKUWIKI_USERNAME: admin | |
DOKUWIKI_FULL_NAME: Administrator | |
DOKUWIKI_PASSWORD: admin | |
DOKUWIKI_EMAIL: [email protected] | |
DOKUWIKI_WIKI_NAME: Example Wiki | |
labels: | |
traefik.enable: "true" | |
traefik.http.routers.dokuwiki.tls: "true" | |
traefik.http.routers.dokuwiki.middlewares: "authelia@docker" | |
traefik.http.routers.dokuwiki.rule: "Host(`doku.example.com`)" | |
traefik.http.services.dokuwiki.loadbalancer.server.port: 8080 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment