MDL-48887 An auth plugin hook enabling removal of redundant redirects
authorBrendan Heywood <brendan@catalyst-au.net>
Tue, 20 Jan 2015 03:25:14 +0000 (14:25 +1100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Thu, 2 Apr 2015 09:08:20 +0000 (11:08 +0200)
This introduces a new hook allowing an auth plugin to redirect to an
external login page directly without redundant redirects to the standard
login page first, or where possible to authenticate the user and simply
continue loading the page without any redirects. For some protocols such
as SAML reducing the number of redirects to the bare minimum greatly
speeds up the login process on high latency networks.

lib/authlib.php
lib/moodlelib.php

index dc2ceb9..cb9ef99 100644 (file)
@@ -435,6 +435,26 @@ class auth_plugin_base {
         //override if needed
     }
 
+    /**
+     * Hook for overriding behaviour before going to the login page.
+     *
+     * This method is called from require_login from potentially any page for
+     * all enabled auth plugins and gives each plugin a chance to redirect
+     * directly to an external login page, or to instantly login a user where
+     * possible.
+     *
+     * If an auth plugin implements this hook, it must not rely on ONLY this
+     * hook in order to work, as there are many ways a user can browse directly
+     * to the standard login page. As a general rule in this case you should
+     * also implement the loginpage_hook as well.
+     *
+     */
+    function pre_loginpage_hook() {
+        // override if needed, eg by redirecting to an external login page
+        // or logging in a user:
+        // complete_user_login($user);
+    }
+
     /**
      * Post authentication hook.
      * This method is called from authenticate_user_login() for all enabled auth plugins.
index 7b74a70..b80bb30 100644 (file)
@@ -2902,8 +2902,22 @@ function require_login($courseorid = null, $autologinguest = true, $cm = null, $
             if (!empty($_SERVER['HTTP_REFERER'])) {
                 $SESSION->fromurl  = $_SERVER['HTTP_REFERER'];
             }
-            redirect(get_login_url());
-            exit; // Never reached.
+
+            // Give auth plugins an opportunity to authenticate or redirect to an external login page
+            $authsequence = get_enabled_auth_plugins(true); // auths, in sequence
+            foreach($authsequence as $authname) {
+                $authplugin = get_auth_plugin($authname);
+                $authplugin->pre_loginpage_hook();
+                if (isloggedin()) {
+                    break;
+                }
+            }
+
+            // If we're still not logged in then go to the login page
+            if (!isloggedin()) {
+                redirect(get_login_url());
+                exit; // Never reached.
+            }
         }
     }