diff --git a/application/controllers/AuthenticationController.php b/application/controllers/AuthenticationController.php
index 8838b61ae..959da8b0b 100644
--- a/application/controllers/AuthenticationController.php
+++ b/application/controllers/AuthenticationController.php
@@ -85,10 +85,16 @@ class AuthenticationController extends ActionController
*/
public function logoutAction()
{
- $this->_helper->layout->setLayout('inline');
$auth = AuthManager::getInstance();
$auth->removeAuthorization();
- $this->redirectToLogin();
+
+ if ($auth->isAuthenticatedFromRemoteUser()) {
+ $this->_helper->layout->setLayout('login');
+ $this->_response->setHttpResponseCode(401);
+ } else {
+ $this->_helper->layout->setLayout('inline');
+ $this->redirectToLogin();
+ }
}
}
// @codingStandardsIgnoreEnd
diff --git a/application/views/scripts/authentication/login.phtml b/application/views/scripts/authentication/login.phtml
index cfa81a9a1..33a9f021c 100644
--- a/application/views/scripts/authentication/login.phtml
+++ b/application/views/scripts/authentication/login.phtml
@@ -23,8 +23,6 @@
* is useful for preserving the detail view and the selection in that case.
*
* refs #4833
- *
- * TODO: Copy this snipped into the new login.phtml
*/
var url = document.URL.match(/(^[^#]*)/)[0] + encodeURIComponent(window.location.hash);
document.getElementById('form_login').action = url;
diff --git a/application/views/scripts/authentication/logout.phtml b/application/views/scripts/authentication/logout.phtml
new file mode 100644
index 000000000..eb0d6dc44
--- /dev/null
+++ b/application/views/scripts/authentication/logout.phtml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+ = t('Logging out...'); ?>
+ = t(
+ 'If this message does not disappear, it might be necessary to quit the ' .
+ 'current session manually by clearing the cache, or by closing the current ' .
+ 'browser session.'
+ ); ?>
+
+
+
+
+
+
+
diff --git a/config/config.ini.in b/config/config.ini.in
index 4b57a23b4..9c6b8d10c 100755
--- a/config/config.ini.in
+++ b/config/config.ini.in
@@ -14,6 +14,10 @@ moduleFolder = "@icingaweb_config_path@/enabledModules"
; won't show up in the list of disabled modules.
; modulePath = "/vagrant/modules:/usr/share/icingaweb/modules"
+; The used authentication-mode can be either "internal" to handle the authentication in IcingaWeb
+; or "external" to delegate the authentication to the used WebServer
+authenticationMode = "internal"
+
[logging]
enable = true
; Writing to a Stream
diff --git a/doc/external_authentication.md b/doc/external_authentication.md
new file mode 100644
index 000000000..240713038
--- /dev/null
+++ b/doc/external_authentication.md
@@ -0,0 +1,90 @@
+# Externel Authentication
+
+It is possible to use the authentication mechanism of the webserver,
+instead of using the internal authentication-manager to
+authenticate users. This might be useful if you only have very few users, and
+user management over *.htaccess* is sufficient, or if you must use some other
+authentication mechanism that is only available through your webserver.
+
+When external authentication is used, Icingaweb will entrust the
+complete authentication process to the external authentication provider (the webserver):
+The provider should take care of authenticating the user and declining
+all requests with invalid or missing credentials. When the authentication
+was succesful, it should provide the authenticated users name to its php-module
+and Icingaweb will assume that the user is authorized to access the page.
+Because of this it is very important that the webservers authentication is
+configured correctly, as wrong configuration could lead to unauthorized
+access to the site, or a broken login-process.
+
+
+## Use External Authentication
+
+Using external authentication in Icingaweb requires two steps to work:
+
+1. The external authentication must be set up correctly to always
+ authenticate the users.
+2. Icingaweb must be configured to use the external authentication.
+
+
+### Prepare the External Authentication Provider
+
+This step depends heavily on the used webserver and authentication
+mechanism you want to use. It is not possible to cover all possibillities
+and you should probably read the documentation for your webserver for
+detailed instructions on how to set up authentication properly.
+
+In general, you need to make sure that:
+
+ - All routes require authentication
+ - Only permitted users are allowed to authenticate
+
+
+#### Example Configuration for Apache and HTTPDigestAuthentication
+
+The following example will show how to enable external authentication in Apache using
+*HTTP Digest Authentication*.
+
+##### Create users
+
+To create users for a digest authentication we can use the tool *htdigest*.
+We choose *.icingawebdigest* as a name for the created file, containing
+the user credentials.
+
+This command will create a new file with the user *jdoe*. *htdigest*
+will prompt you for your password, after it has been executed. If you
+want to add more users to the file you need to ommit the *-c* parameter
+in all further commands to avoInid the file to be overwritten.
+
+
+ sudo htdigest -c /etc/httpd/conf.d/.icingawebdigest "Icingaweb 2" jdoe
+
+
+##### Set up authentication
+
+The webserver should require authentication for all public icingaweb files.
+
+
+
+ AuthType digest
+ AuthName "Icingaweb 2"
+ AuthDigestProvider file
+ AuthUserFile /etc/httpd/conf.d/.icingawebdigest
+ Require valid-user
+
+
+
+### Prepare Icingaweb
+
+When the external authentication is set up correctly, we need
+to configure IcingaWeb to use it as an authentication source. The
+configuration key *authenticationMode* in the section *global* defines
+if the authentication should be handled internally or externally. Since
+we want to delegate the authentication to the Webserver we choose
+"external" as the new value:
+
+
+ [global]
+ ; ...
+ authenticationMode = "external"
+ ; ...
+
diff --git a/library/Icinga/Application/Web.php b/library/Icinga/Application/Web.php
index 470f3e54a..a334d36c3 100644
--- a/library/Icinga/Application/Web.php
+++ b/library/Icinga/Application/Web.php
@@ -230,6 +230,11 @@ class Web extends ApplicationBootstrap
{
$authenticationManager = AuthenticationManager::getInstance();
+
+ if ($this->getConfig()->get('global')->get('authenticationMode', 'internal') === 'external') {
+ $authenticationManager->authenticateFromRemoteUser();
+ }
+
if ($authenticationManager->isAuthenticated() === true) {
$user = $authenticationManager->getUser();
diff --git a/library/Icinga/Authentication/Manager.php b/library/Icinga/Authentication/Manager.php
index 6307211a1..a818c6081 100644
--- a/library/Icinga/Authentication/Manager.php
+++ b/library/Icinga/Authentication/Manager.php
@@ -52,6 +52,7 @@ use Icinga\Authentication\Backend\LdapUserBackend;
**/
class Manager
{
+
/**
* Singleton instance
*
@@ -59,6 +60,13 @@ class Manager
*/
private static $instance;
+ /**
+ * If the user was authenticated from the REMOTE_USER server variable
+ *
+ * @var Boolean
+ */
+ private $fromRemoteUser = false;
+
/**
* Instance of authenticated user
*
@@ -387,6 +395,27 @@ class Manager
$this->user = Session::getSession()->get('user');
}
+ /**
+ * Tries to authenticate the user from the session, and then from the REMOTE_USER superglobal, that can be set by
+ * an external authentication provider.
+ */
+ public function authenticateFromRemoteUser()
+ {
+ $this->fromRemoteUser = true;
+ $this->authenticateFromSession();
+ if ($this->user !== null) {
+ if (array_key_exists('REMOTE_USER', $_SERVER) && $this->user->getUsername() !== $_SERVER["REMOTE_USER"]) {
+ // Remote user has changed, clear all sessions
+ $this->removeAuthorization();
+ }
+ return;
+ }
+ if (array_key_exists('REMOTE_USER', $_SERVER) && $_SERVER["REMOTE_USER"]) {
+ $this->user = new User($_SERVER["REMOTE_USER"]);
+ $this->persistCurrentUser();
+ }
+ }
+
/**
* Returns true when the user is currently authenticated
*
@@ -472,4 +501,12 @@ class Manager
{
return $this->user->getGroups();
}
+
+ /**
+ * If the session was established from the REMOTE_USER server variable.
+ */
+ public function isAuthenticatedFromRemoteUser()
+ {
+ return $this->fromRemoteUser;
+ }
}
diff --git a/library/Icinga/Web/Widget/Chart/PieChart.php b/library/Icinga/Web/Widget/Chart/PieChart.php
index 0e4547135..edc4e78fe 100644
--- a/library/Icinga/Web/Widget/Chart/PieChart.php
+++ b/library/Icinga/Web/Widget/Chart/PieChart.php
@@ -43,7 +43,7 @@ class PieChart implements Widget
*/
private $template =<<<'EOD'
-