diff options
-rw-r--r-- | app/Controller/Base.php | 43 | ||||
-rw-r--r-- | app/Model/LastLogin.php | 1 | ||||
-rw-r--r-- | app/Model/ReverseProxyAuth.php | 70 | ||||
-rw-r--r-- | app/common.php | 5 | ||||
-rw-r--r-- | config.default.php | 9 |
5 files changed, 109 insertions, 19 deletions
diff --git a/app/Controller/Base.php b/app/Controller/Base.php index 2739c5ac..7b1cfd85 100644 --- a/app/Controller/Base.php +++ b/app/Controller/Base.php @@ -12,22 +12,24 @@ use Model\LastLogin; * * @package controller * @author Frederic Guillot - * @property \Model\Acl $acl - * @property \Model\Action $action - * @property \Model\Board $board - * @property \Model\Category $category - * @property \Model\Comment $comment - * @property \Model\Config $config - * @property \Model\File $file - * @property \Model\Google $google - * @property \Model\GitHub $gitHub - * @property \Model\LastLogin $lastLogin - * @property \Model\Ldap $ldap - * @property \Model\Project $project - * @property \Model\RememberMe $rememberMe - * @property \Model\SubTask $subTask - * @property \Model\Task $task - * @property \Model\User $user + * + * @property \Model\Acl $acl + * @property \Model\Action $action + * @property \Model\Board $board + * @property \Model\Category $category + * @property \Model\Comment $comment + * @property \Model\Config $config + * @property \Model\File $file + * @property \Model\Google $google + * @property \Model\GitHub $gitHub + * @property \Model\LastLogin $lastLogin + * @property \Model\Ldap $ldap + * @property \Model\Project $project + * @property \Model\RememberMe $rememberMe + * @property \Model\ReverseProxyAuth $reverseProxyAuth + * @property \Model\SubTask $subTask + * @property \Model\Task $task + * @property \Model\User $user */ abstract class Base { @@ -123,11 +125,14 @@ abstract class Base // Authentication if (! $this->acl->isLogged() && ! $this->acl->isPublicAction($controller, $action)) { - // Try the remember me authentication first + // Try the "remember me" authentication first if (! $this->rememberMe->authenticate()) { - // Redirect to the login form if not authenticated - $this->response->redirect('?controller=user&action=login'); + // Automatic reverse proxy header authentication + if(! (REVERSE_PROXY_AUTH && $this->reverseProxyAuth->authenticate()) ) { + // Redirect to the login form if not authenticated + $this->response->redirect('?controller=user&action=login'); + } } else { diff --git a/app/Model/LastLogin.php b/app/Model/LastLogin.php index db4c4a57..e2ea63e1 100644 --- a/app/Model/LastLogin.php +++ b/app/Model/LastLogin.php @@ -34,6 +34,7 @@ class LastLogin extends Base const AUTH_LDAP = 'ldap'; const AUTH_GOOGLE = 'google'; const AUTH_GITHUB = 'github'; + const AUTH_REVERSE_PROXY = 'reverse_proxy'; /** * Create a new record diff --git a/app/Model/ReverseProxyAuth.php b/app/Model/ReverseProxyAuth.php new file mode 100644 index 00000000..1b9ed06c --- /dev/null +++ b/app/Model/ReverseProxyAuth.php @@ -0,0 +1,70 @@ +<?php + +namespace Model; + +use Core\Security; + +/** + * ReverseProxyAuth model + * + * @package model + * @author Sylvain VeyriƩ + */ +class ReverseProxyAuth extends Base +{ + /** + * Authenticate the user with the HTTP header + * + * @access public + * @return bool + */ + public function authenticate() + { + if (isset($_SERVER[REVERSE_PROXY_USER_HEADER])) { + + $login = $_SERVER[REVERSE_PROXY_USER_HEADER]; + $userModel = new User($this->db, $this->event); + $user = $userModel->getByUsername($login); + + if (! $user) { + $this->createUser($login); + $user = $userModel->getByUsername($login); + } + + // Create the user session + $userModel->updateSession($user); + + // Update login history + $lastLogin = new LastLogin($this->db, $this->event); + $lastLogin->create( + LastLogin::AUTH_REVERSE_PROXY, + $user['id'], + $userModel->getIpAddress(), + $userModel->getUserAgent() + ); + + return true; + } + + return false; + } + + /** + * Create automatically a new local user after the authentication + * + * @access private + * @param string $login Username + * @return bool + */ + private function createUser($login) + { + $userModel = new User($this->db, $this->event); + + return $userModel->create(array( + 'email' => strpos($login, '@') !== false ? $login : '', + 'username' => $login, + 'is_admin' => REVERSE_PROXY_DEFAULT_ADMIN === $login, + 'is_ldap_user' => 1, + )); + } +} diff --git a/app/common.php b/app/common.php index c33d5592..312b930b 100644 --- a/app/common.php +++ b/app/common.php @@ -58,6 +58,11 @@ defined('GITHUB_AUTH') or define('GITHUB_AUTH', false); defined('GITHUB_CLIENT_ID') or define('GITHUB_CLIENT_ID', ''); defined('GITHUB_CLIENT_SECRET') or define('GITHUB_CLIENT_SECRET', ''); +// Proxy authentication +defined('REVERSE_PROXY_AUTH') or define('REVERSE_PROXY_AUTH', false); +defined('REVERSE_PROXY_USER_HEADER') or define('REVERSE_PROXY_USER_HEADER', 'REMOTE_USER'); +defined('REVERSE_PROXY_DEFAULT_ADMIN') or define('REVERSE_PROXY_DEFAULT_ADMIN', ''); + $loader = new Loader; $loader->execute(); diff --git a/config.default.php b/config.default.php index 027d8417..b1028767 100644 --- a/config.default.php +++ b/config.default.php @@ -71,3 +71,12 @@ define('GITHUB_CLIENT_ID', ''); // GitHub client secret key (Copy it from your settings -> Applications -> Developer applications) define('GITHUB_CLIENT_SECRET', ''); + +// Enable/disable the reverse proxy authentication +define('REVERSE_PROXY_AUTH', false); + +// Header name to use for the username +define('REVERSE_PROXY_USER_HEADER', 'REMOTE_USER'); + +// Username of the admin, by default blank +define('REVERSE_PROXY_DEFAULT_ADMIN', ''); |