Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-48887

Add new auth pre_loginpage_hook() (save redirects, implement autologins...)

    XMLWordPrintable

Details

    • MOODLE_26_STABLE, MOODLE_27_STABLE, MOODLE_28_STABLE, MOODLE_29_STABLE
    • MOODLE_29_STABLE
    • MDL-48887-fastredirect
    • Hide

      I've implemented this new hook in two separate plugins to demonstrate it's usefulness in a variety of auth protocols:

      Test 1: Using the basic auth plugin

      Install the moodle_auth_basic plugin with support for this proposed hook:

      https://github.com/brendanheywood/moodle-auth_basic/tree/MDL-48887

      • turn on the basic auth plugin, and in the settings set 'Only basic' to 'No'
      • find or create a user with a manual auth and log in as them using curl with basic auth and you should see them logged directly in without any redirects at all:

      brendan@silverbirch:/var/www/cqu-he-moodle$ time curl -c /tmp/cookies -v -L --user 'user:pass' http://he.moodle.cqu.local/local/linkchecker_robot/tests/test1.php 2>&1 | grep -P 'GET|Location'
      > GET /local/linkchecker_robot/tests/test1.php HTTP/1.1

      real 0m0.596s
      user 0m0.004s
      sys 0m0.012s

      • without this hook you would see a slower process with redundant redirects:

      brendan@silverbirch:/var/www/cqu-he-moodle$ time curl -c /tmp/cookies -v -L --user 'user:pass' http://he.moodle.cqu.local/local/linkchecker_robot/tests/test1.php 2>&1 | grep -P 'GET|Location'
      > GET /local/linkchecker_robot/tests/test1.php HTTP/1.1
      < Location: http://he.moodle.cqu.local/login/index.php
      > GET /login/index.php HTTP/1.1
      < Location: http://he.moodle.cqu.local/local/linkchecker_robot/tests/test1.php
      > GET /local/linkchecker_robot/tests/test1.php HTTP/1.1

      real 0m1.004s
      user 0m0.000s
      sys 0m0.012s

      Test 2: Using the saml auth plugin

      I've forked the saml plugin by Piers and added support for the proposed hook here:

      https://github.com/brendanheywood/moodle-auth_saml/tree/MDL-48887

      To test:
      1) setup an IDP somewhere such as testshib.org
      2) turn off dual login in saml auth plugin settings
      3) In chrome open dev tools and preserve the network log
      4) Go to an authenticated page

      You should see 5 redirects with the new hook instead of 6. The remaining redirects could also be removed by re-implementing the saml plugin using the saml lib instead of the full simplesamlphp app.

      Show
      I've implemented this new hook in two separate plugins to demonstrate it's usefulness in a variety of auth protocols: Test 1: Using the basic auth plugin Install the moodle_auth_basic plugin with support for this proposed hook: https://github.com/brendanheywood/moodle-auth_basic/tree/MDL-48887 turn on the basic auth plugin, and in the settings set 'Only basic' to 'No' find or create a user with a manual auth and log in as them using curl with basic auth and you should see them logged directly in without any redirects at all: brendan@silverbirch:/var/www/cqu-he-moodle$ time curl -c /tmp/cookies -v -L --user 'user:pass' http://he.moodle.cqu.local/local/linkchecker_robot/tests/test1.php 2>&1 | grep -P 'GET|Location' > GET /local/linkchecker_robot/tests/test1.php HTTP/1.1 real 0m0.596s user 0m0.004s sys 0m0.012s without this hook you would see a slower process with redundant redirects: brendan@silverbirch:/var/www/cqu-he-moodle$ time curl -c /tmp/cookies -v -L --user 'user:pass' http://he.moodle.cqu.local/local/linkchecker_robot/tests/test1.php 2>&1 | grep -P 'GET|Location' > GET /local/linkchecker_robot/tests/test1.php HTTP/1.1 < Location: http://he.moodle.cqu.local/login/index.php > GET /login/index.php HTTP/1.1 < Location: http://he.moodle.cqu.local/local/linkchecker_robot/tests/test1.php > GET /local/linkchecker_robot/tests/test1.php HTTP/1.1 real 0m1.004s user 0m0.000s sys 0m0.012s Test 2: Using the saml auth plugin I've forked the saml plugin by Piers and added support for the proposed hook here: https://github.com/brendanheywood/moodle-auth_saml/tree/MDL-48887 To test: 1) setup an IDP somewhere such as testshib.org 2) turn off dual login in saml auth plugin settings 3) In chrome open dev tools and preserve the network log 4) Go to an authenticated page You should see 5 redirects with the new hook instead of 6. The remaining redirects could also be removed by re-implementing the saml plugin using the saml lib instead of the full simplesamlphp app.

    Description

      Looking at a typical login flow in the browser reveals a lot of redirects. ie if we use the saml auth plugin, and assume the best case scenario on the saml IDP side where the user is already logged in, but no session on the moodle side, then we still end up with a staggering 7 redirects between clicking on the page we want and then actually being served that page. The saml protocol itself only requires a single redirect, so the rest are potentially redundant in some way.

      On networks with high latency, eg mobile, each redirect can be upwards of 100's of ms so combined they can easily account for seconds of time wasted for no reason.

      Some of the issues / solutions are in core, some others would be in the various auth plugins like saml. eg a typical saml flow:

      Try to view a protect page eg /course/view.php?id=10

      1) 303 redirect to /login/index.php
      2) 303 redirect to /auth/saml/login.php
      3) 302 redirect to /auth/saml/index.php?wantsurl=XX
      4) 302 redirect to IDP url
      5) 200 IDP redirects back to simplesaml
      6) 303 simplesaml redirect back to /auth/saml/index/php?YYY
      7) 303 redirect to original course url
      8) 200 render of desired url

      Some ideas:

      a) If 'alternateloginurl' is forced in config.php and so unchangeable, we can skip 2 redirects and redirect directly to url #3 or possibly even url #4. The login link in the header on public pages would link directly to this as well. ie add logic to get_login_url() in moodlelib.php Or make this is tick box in the auth settings page eg 'Fast redirect to alternate login page'. Bonus points: there still seems to be a lot of places in core hard code /login/index.php instead of calling get_login_url() This would have potential benefits across many auth plugin types without them needing to be modified.

      b) Redirect #6 could also be removed if there was an optional moodle auth hook which allows an auth plugin code to run just prior to the user being redirected to the login page, and give it a chance to authenticate them and then keep going. ie the simplesaml plugin can check the dual session, confirm it's validity and then log the user in and continue. Same for other auth types without password forms, ie an external cookie, http header, ip check etc. Something like prelogin_hook(). So if this new API hook was added the redirect to the IDP could be handled directly here, and avoid the 'alternateloginurl' solution above, saving at least 3 redirects with a single API hook.

      So thoughts and feedback?

      Attachments

        Activity

          People

            brendanheywood Brendan Heywood
            brendanheywood Brendan Heywood
            Dan Poltawski Dan Poltawski
            Eloy Lafuente (stronk7) Eloy Lafuente (stronk7)
            Rajesh Taneja Rajesh Taneja
            David Woloszyn, Huong Nguyen, Jake Dallimore, Meirza, Michael Hawkins, Raquel Ortega, Safat Shahin, Stevani Andolo, Matteo Scaramuccia, David Woloszyn, Huong Nguyen, Jake Dallimore, Meirza, Michael Hawkins, Raquel Ortega, Safat Shahin, Stevani Andolo
            Votes:
            2 Vote for this issue
            Watchers:
            9 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              11/May/15