diff --git a/_test/tests/inc/Action/general.test.php b/_test/tests/inc/Action/general.test.php
index 9aacfbf96bb15416ca4186c6298134fd7bc380c7..aafeb4a83748f8dd88b4d3b60a51a811b7c20914 100644
--- a/_test/tests/inc/Action/general.test.php
+++ b/_test/tests/inc/Action/general.test.php
@@ -26,7 +26,7 @@ class action_general extends DokuWikiTest {
             array('Revert', AUTH_ADMIN, array('exists' => true, 'ismanager' => false)),
             array('Revert', AUTH_EDIT, array('exists' => true, 'ismanager' => true)),
 
-            array('Admin', AUTH_ADMIN, array('exists' => true, 'ismanager' => false)),
+            array('Admin', AUTH_READ, array('exists' => true, 'ismanager' => false)), // let in, check later again
             array('Admin', AUTH_READ, array('exists' => true, 'ismanager' => true)), // let in, check later again
 
             array('Check', AUTH_READ, array('exists' => true, 'ismanager' => false)), // sensible?
diff --git a/_test/tests/inc/template_include_page.test.php b/_test/tests/inc/template_include_page.test.php
index 7dd13ba236be6a3f41f010c4573e7489e1371dcc..ea9e895581fb361ebc1703aaae95219d045a322b 100644
--- a/_test/tests/inc/template_include_page.test.php
+++ b/_test/tests/inc/template_include_page.test.php
@@ -32,7 +32,9 @@ class template_pagetitle_test extends DokuWikiTest {
     }
 
     function test_adminPluginTitle() {
-        global $ID,$ACT,$INPUT,$conf;
+        global $ID,$ACT,$INPUT,$conf,$INFO;
+        $INFO['isadmin'] = true;
+        $INFO['ismanager'] = true;
 
         if (!plugin_load('admin','revert')) {
             $this->markTestSkipped('Revert plugin not found, unable to test admin plugin titles');
diff --git a/inc/Action/Admin.php b/inc/Action/Admin.php
index 8d43057888fdd26c00e55f5cdc40bedcee954796..cc6dfd74fd052d972156ed02cfbec796feeb6ff2 100644
--- a/inc/Action/Admin.php
+++ b/inc/Action/Admin.php
@@ -15,22 +15,11 @@ class Admin extends AbstractUserAction {
 
     /** @inheritdoc */
     public function minimumPermission() {
-        global $INFO;
-
-        if($INFO['ismanager']) {
-            return AUTH_READ; // let in check later
-        } else {
-            return AUTH_ADMIN;
-        }
+        return AUTH_READ; // let in check later
     }
 
     public function checkPreconditions() {
         parent::checkPreconditions();
-
-        global $INFO;
-        if(!$INFO['ismanager']) {
-            throw new ActionException('denied');
-        }
     }
 
     public function preProcess() {
@@ -41,7 +30,7 @@ class Admin extends AbstractUserAction {
         if(($page = $INPUT->str('page', '', true)) != '') {
             /** @var $plugin \DokuWiki_Admin_Plugin */
             if($plugin = plugin_getRequestAdminPlugin()) { // FIXME this method does also permission checking
-                if($plugin->forAdminOnly() && !$INFO['isadmin']) {
+                if(!$plugin->isAccessibleByCurrentUser()) {
                     throw new ActionException('denied');
                 }
                 $plugin->handle();
diff --git a/inc/Menu/Item/Admin.php b/inc/Menu/Item/Admin.php
index 7302f0f34fd42eabc96f886668d8efb691c8a0a1..e5506c220299302edb5a4ee854f2673af300dc74 100644
--- a/inc/Menu/Item/Admin.php
+++ b/inc/Menu/Item/Admin.php
@@ -11,14 +11,18 @@ class Admin extends AbstractItem {
 
     /** @inheritdoc */
     public function __construct() {
-        global $INFO;
         parent::__construct();
 
         $this->svg = DOKU_INC . 'lib/images/menu/settings.svg';
+    }
+
+    /** @inheritdoc */
+    public function visibleInContext($ctx)
+    {
+        global $INFO;
+        if(!$INFO['ismanager']) return false;
 
-        if(!$INFO['ismanager']) {
-            throw new \RuntimeException("admin is for managers only");
-        }
+        return parent::visibleInContext($ctx);
     }
 
 }
diff --git a/inc/Ui/Admin.php b/inc/Ui/Admin.php
index aa3b8b99e281c17e5c20b0a5b7159b495acc3e4c..20416e1371c86bc65eff9589674472a9f9ec91be 100644
--- a/inc/Ui/Admin.php
+++ b/inc/Ui/Admin.php
@@ -12,6 +12,9 @@ namespace dokuwiki\Ui;
  */
 class Admin extends Ui {
 
+    protected $forAdmins = array('usermanager', 'acl', 'extension', 'config', 'styling');
+    protected $forManagers = array('revert', 'popularity');
+    /** @var array[] */
     protected $menu;
 
     /**
@@ -24,58 +27,30 @@ class Admin extends Ui {
         echo '<div class="ui-admin">';
         echo p_locale_xhtml('admin');
         $this->showSecurityCheck();
-        $this->showAdminMenu();
-        $this->showManagerMenu();
+        $this->showMenu('admin');
+        $this->showMenu('manager');
         $this->showVersion();
-        $this->showPluginMenu();
+        $this->showMenu('other');
         echo '</div>';
     }
 
     /**
-     * Display the standard admin tasks
+     * Show the given menu of available plugins
+     *
+     * @param string $type admin|manager|other
      */
-    protected function showAdminMenu() {
-        /** @var \DokuWiki_Auth_Plugin $auth */
-        global $auth;
-        global $INFO;
-
-        if(!$INFO['isadmin']) return;
-
-        // user manager only if the auth backend supports it
-        if(!$auth || !$auth->canDo('getUsers') ) {
-            if(isset($this->menu['usermanager'])) unset($this->menu['usermanager']);
+    protected function showMenu($type) {
+        if (!$this->menu[$type]) return;
+
+        if ($type === 'other') {
+            echo p_locale_xhtml('adminplugins');
+            $class = 'admin_plugins';
+        } else {
+            $class = 'admin_tasks';
         }
 
-        echo '<ul class="admin_tasks">';
-        foreach(array('usermanager','acl', 'extension', 'config', 'styling') as $plugin) {
-            if(!isset($this->menu[$plugin])) continue;
-            $this->showMenuItem($this->menu[$plugin]);
-            unset($this->menu[$plugin]);
-        }
-        echo '</ul>';
-    }
-
-    /**
-     * Display the standard manager tasks
-     */
-    protected function showManagerMenu() {
-        echo '<ul class="admin_tasks">';
-        foreach(array('revert','popularity') as $plugin) {
-            if(!isset($this->menu[$plugin])) continue;
-            $this->showMenuItem($this->menu[$plugin]);
-            unset($this->menu[$plugin]);
-        }
-        echo '</ul>';
-    }
-
-    /**
-     * Display all the remaining plugins
-     */
-    protected function showPluginMenu() {
-        if(!count($this->menu)) return;
-        echo p_locale_xhtml('adminplugins');
-        echo '<ul class="admin_plugins">';
-        foreach ($this->menu as $item) {
+        echo "<ul class=\"$class\">";
+        foreach ($this->menu[$type] as $item) {
             $this->showMenuItem($item);
         }
         echo '</ul>';
@@ -104,7 +79,9 @@ class Admin extends Ui {
         if(substr($conf['savedir'], 0, 2) !== './') return;
         echo '<a style="border:none; float:right;"
                 href="http://www.dokuwiki.org/security#web_access_security">
-                <img src="' . DOKU_URL . $conf['savedir'] . '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png" alt="Your data directory seems to be protected properly."
+                <img src="' . DOKU_URL . $conf['savedir'] .
+                '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png" 
+                alt="Your data directory seems to be protected properly."
                 onerror="this.parentNode.style.display=\'none\'" /></a>';
     }
 
@@ -136,19 +113,27 @@ class Admin extends Ui {
      * @return array list of plugins with their properties
      */
     protected function getPluginList() {
-        global $INFO;
         global $conf;
 
         $pluginlist = plugin_list('admin');
-        $menu = array();
+        $menu = ['admin' => [], 'manager' => [], 'other' => []];
+
         foreach($pluginlist as $p) {
             /** @var \DokuWiki_Admin_Plugin $obj */
-            if(($obj = plugin_load('admin', $p)) === null) continue;
+            if (($obj = plugin_load('admin', $p)) === null) continue;
 
             // check permissions
-            if($obj->forAdminOnly() && !$INFO['isadmin']) continue;
+            if (!$obj->isAccessibleByCurrentUser()) continue;
+
+            if (in_array($p, $this->forAdmins, true)) {
+                $type = 'admin';
+            } elseif (in_array($p, $this->forManagers, true)){
+                $type = 'manager';
+            } else {
+                $type = 'other';
+            }
 
-            $menu[$p] = array(
+            $menu[$type][$p] = array(
                 'plugin' => $p,
                 'prompt' => $obj->getMenuText($conf['lang']),
                 'icon' => $obj->getMenuIcon(),
@@ -157,17 +142,26 @@ class Admin extends Ui {
         }
 
         // sort by name, then sort
-        uasort(
-            $menu,
-            function ($a, $b) {
-                $strcmp = strcasecmp($a['prompt'], $b['prompt']);
-                if($strcmp != 0) return $strcmp;
-                if($a['sort'] == $b['sort']) return 0;
-                return ($a['sort'] < $b['sort']) ? -1 : 1;
-            }
-        );
+        uasort($menu['admin'], [$this, 'menuSort']);
+        uasort($menu['manager'], [$this, 'menuSort']);
+        uasort($menu['other'], [$this, 'menuSort']);
 
         return $menu;
     }
 
+    /**
+     * Custom sorting for admin menu
+     *
+     * We sort alphabetically first, then by sort value
+     *
+     * @param array $a
+     * @param array $b
+     * @return int
+     */
+    protected function menuSort ($a, $b) {
+        $strcmp = strcasecmp($a['prompt'], $b['prompt']);
+        if($strcmp != 0) return $strcmp;
+        if($a['sort'] === $b['sort']) return 0;
+        return ($a['sort'] < $b['sort']) ? -1 : 1;
+    }
 }
diff --git a/inc/pluginutils.php b/inc/pluginutils.php
index a395be43512ba5c4afe766353797200f67582ca3..0cd113b14825258485dcba8328af3d97216b1781 100644
--- a/inc/pluginutils.php
+++ b/inc/pluginutils.php
@@ -123,7 +123,7 @@ function plugin_getRequestAdminPlugin(){
                 /** @var $admin_plugin DokuWiki_Admin_Plugin */
                 $admin_plugin = plugin_load('admin', $page);
                 // verify
-                if ($admin_plugin && $admin_plugin->forAdminOnly() && !$INFO['isadmin']) {
+                if ($admin_plugin && !$admin_plugin->isAccessibleByCurrentUser()) {
                     $admin_plugin = null;
                     $INPUT->remove('page');
                     msg('For admins only',-1);
diff --git a/lib/plugins/acl/action.php b/lib/plugins/acl/action.php
index a7226f598c8ef7db825003a8e59a7811f8ccb4a4..1d6d05b806f58b33ab52439630b21e946f44d4b6 100644
--- a/lib/plugins/acl/action.php
+++ b/lib/plugins/acl/action.php
@@ -34,7 +34,7 @@ class action_plugin_acl extends DokuWiki_Action_Plugin {
      * @return void
      */
 
-    public function handle_ajax_call_acl(Doku_Event &$event, $param) {
+    public function handle_ajax_call_acl(Doku_Event $event, $param) {
         if($event->data !== 'plugin_acl') {
             return;
         }
@@ -44,7 +44,10 @@ class action_plugin_acl extends DokuWiki_Action_Plugin {
         global $ID;
         global $INPUT;
 
-        if(!auth_isadmin()) {
+        /** @var $acl admin_plugin_acl */
+        $acl = plugin_load('admin', 'acl');
+
+        if(!$acl->isAccessibleByCurrentUser()) {
             echo 'for admins only';
             return;
         }
@@ -54,9 +57,6 @@ class action_plugin_acl extends DokuWiki_Action_Plugin {
         }
 
         $ID = getID();
-
-        /** @var $acl admin_plugin_acl */
-        $acl = plugin_load('admin', 'acl');
         $acl->handle();
 
         $ajax = $INPUT->str('ajax');
diff --git a/lib/plugins/admin.php b/lib/plugins/admin.php
index 4e1cbbb337c11393ab40afeaa4b769a9e35c11cd..d9c7d296998b4f6bbdc5041aa7cc45cec636d58b 100644
--- a/lib/plugins/admin.php
+++ b/lib/plugins/admin.php
@@ -72,6 +72,31 @@ class DokuWiki_Admin_Plugin extends DokuWiki_Plugin {
         trigger_error('html() not implemented in '.get_class($this), E_USER_WARNING);
     }
 
+    /**
+     * Checks if access should be granted to this admin plugin
+     *
+     * @return bool true if the current user may access this admin plugin
+     */
+    public function isAccessibleByCurrentUser() {
+        global $INFO;
+
+        $data = [];
+        $data['instance'] = $this;
+        $data['hasAccess'] = false;
+
+        $event = new Doku_Event('ADMINPLUGIN_ACCESS_CHECK', $data);
+        if($event->advise_before()) {
+            if ($this->forAdminOnly()) {
+                $data['hasAccess'] = $INFO['isadmin'];
+            } else {
+                $data['hasAccess'] = $INFO['ismanager'];
+            }
+        }
+        $event->advise_after();
+
+        return $data['hasAccess'];
+    }
+
     /**
      * Return true for access only by admins (config:superuser) or false if managers are allowed as well
      *
diff --git a/lib/plugins/extension/action.php b/lib/plugins/extension/action.php
index 9e48f134b1f7d527804450ddf60d73d0d33febee..4af84f8df03f52b5037c7c18f75eda6109798fc9 100644
--- a/lib/plugins/extension/action.php
+++ b/lib/plugins/extension/action.php
@@ -36,7 +36,9 @@ class action_plugin_extension extends DokuWiki_Action_Plugin {
         $event->preventDefault();
         $event->stopPropagation();
 
-        if(empty($_SERVER['REMOTE_USER']) || !auth_isadmin($_SERVER['REMOTE_USER'], $USERINFO['grps'])) {
+        /** @var admin_plugin_extension $admin */
+        $admin = plugin_load('admin', 'extension');
+        if(!$admin->isAccessibleByCurrentUser()) {
             http_status(403);
             echo 'Forbidden';
             exit;
diff --git a/lib/plugins/styling/action.php b/lib/plugins/styling/action.php
index 896e14bef8ed60d137ea28591760688bfe30d236..2190fd61dd900bd359713cd30fb4693d8aba8e27 100644
--- a/lib/plugins/styling/action.php
+++ b/lib/plugins/styling/action.php
@@ -41,7 +41,9 @@ class action_plugin_styling extends DokuWiki_Action_Plugin {
         global $ACT;
         global $INPUT;
         if($ACT != 'admin' || $INPUT->str('page') != 'styling') return;
-        if(!auth_isadmin()) return;
+        /** @var admin_plugin_styling $admin */
+        $admin = plugin_load('admin', 'styling');
+        if(!$admin->isAccessibleByCurrentUser()) return;
 
         // set preview
         $len = count($event->data['link']);
diff --git a/lib/plugins/styling/popup.php b/lib/plugins/styling/popup.php
index 964b19e296a1d2217591e5dd3f76d3d0003168f8..4a1735ccc47248102edeba550cb153ac2c8ac74f 100644
--- a/lib/plugins/styling/popup.php
+++ b/lib/plugins/styling/popup.php
@@ -8,7 +8,7 @@ header('X-UA-Compatible: IE=edge,chrome=1');
 
 /** @var admin_plugin_styling $plugin */
 $plugin = plugin_load('admin', 'styling');
-if(!auth_isadmin()) die('only admins allowed');
+if(!$plugin->isAccessibleByCurrentUser()) die('only admins allowed');
 $plugin->ispopup = true;
 
 // handle posts
diff --git a/lib/plugins/usermanager/admin.php b/lib/plugins/usermanager/admin.php
index 6d9bf3b202bbd5067f9338e9523ed57500f3fe35..3148971ce19f137816ae1f333716ec80d0f7bdd1 100644
--- a/lib/plugins/usermanager/admin.php
+++ b/lib/plugins/usermanager/admin.php
@@ -297,6 +297,24 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
         return true;
     }
 
+    /**
+     * User Manager is only available if the auth backend supports it
+     *
+     * @inheritdoc
+     * @return bool
+     */
+    public function isAccessibleByCurrentUser()
+    {
+        /** @var DokuWiki_Auth_Plugin $auth */
+        global $auth;
+        if(!$auth || !$auth->canDo('getUsers') ) {
+            return false;
+        }
+
+        return parent::isAccessibleByCurrentUser();
+    }
+
+
     /**
      * Display form to add or modify a user
      *