Moodle Mobile
  1. Moodle Mobile
  2. MOBILE-113

Support for any auth plugin that performs any type of SSO: CAS, LDAP Single Sign-On and Shibboleth

    Details

    • Type: New Feature New Feature
    • Status: Development in progress
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 1.0
    • Fix Version/s: None
    • Component/s: Web
    • Labels:
    • Affected Branches:
      MOODLE_10_STABLE
    • Rank:
      21092

      Description

      Please build in support for CAS single sign-on in the Mobile app for iOS.

      1. sso_mobile_auth.diff
        2 kB
        Asaf Ohayon
      2. uoetoken.php
        11 kB
        Dan Small

        Issue Links

          Activity

          Hide
          Erik Ordway added a comment -

          Initially I thought it would not be possible but after reading this:
          http://floatlearning.com/2011/01/connecting-ios-drupal-and-cas/
          It seems like others have done it. Drupal uses the same phpcas base code so it should be possible.

          Show
          Erik Ordway added a comment - Initially I thought it would not be possible but after reading this: http://floatlearning.com/2011/01/connecting-ios-drupal-and-cas/ It seems like others have done it. Drupal uses the same phpcas base code so it should be possible.
          Hide
          Dongsheng Cai added a comment -

          Hi Erik

          Thanks for the link, it would be a little easier to do it in moodle, we already have CAS plugin.

          Show
          Dongsheng Cai added a comment - Hi Erik Thanks for the link, it would be a little easier to do it in moodle, we already have CAS plugin.
          Hide
          Patrick Pollet added a comment -

          Yes CAS servers do have a REST API see https://wiki.jasig.org/display/CASUM/RESTful+API
          but in that document it is stated that CAS admins should turn it off since :

          " There are some serious issues to consider in enabling that, not least of which is that naively implemented the REST endpoint becomes a tremendously convenient target for brute force dictionary attacks on your CAS server."

          Cheers.

          Show
          Patrick Pollet added a comment - Yes CAS servers do have a REST API see https://wiki.jasig.org/display/CASUM/RESTful+API but in that document it is stated that CAS admins should turn it off since : " There are some serious issues to consider in enabling that, not least of which is that naively implemented the REST endpoint becomes a tremendously convenient target for brute force dictionary attacks on your CAS server." Cheers.
          Hide
          Jérôme Mouneyrac added a comment -

          I added LDAP support. I guess the solution should be generic to any authentication plugins. Some authentication plugin that doesn't support login/password connection (like oauth2, webservice,...) would return false and fail. All other authentication should try to authenticate against their own method. It's quite the common way to proceed with authentication (=> all enabled authentication are checked till once succeed).

          Show
          Jérôme Mouneyrac added a comment - I added LDAP support. I guess the solution should be generic to any authentication plugins. Some authentication plugin that doesn't support login/password connection (like oauth2, webservice,...) would return false and fail. All other authentication should try to authenticate against their own method. It's quite the common way to proceed with authentication (=> all enabled authentication are checked till once succeed).
          Hide
          Jérôme Mouneyrac added a comment -

          I linked the MDL issue. Once the MDL issue is resolved this will automatically works with the Mobile app. No code modification needed on the app side.

          Show
          Jérôme Mouneyrac added a comment - I linked the MDL issue. Once the MDL issue is resolved this will automatically works with the Mobile app. No code modification needed on the app side.
          Hide
          J Ross Nicoll added a comment -

          Even if CAS isn't a possibility, being able to configure to fall back on LDAP would work for us and I suspect many places. We use CAS because users like SSO, but it's just backed on an LDAP server behind the scenes.

          Show
          J Ross Nicoll added a comment - Even if CAS isn't a possibility, being able to configure to fall back on LDAP would work for us and I suspect many places. We use CAS because users like SSO, but it's just backed on an LDAP server behind the scenes.
          Hide
          Jérôme Mouneyrac added a comment -

          Hi,
          I've been testing the My Moodle app with a LDAP server (OpenDS that I installed on my local machine) and it works. Reading the code, the current implementation is already generic.

          Could everybody having the issue tell:
          1- if you can use the app with manual user (if you can't, then CAS/LDAP is not the issue, it's probably a misconfig or different bug)
          2- the authentication protocol that doesn't work: LDAP / CAS / ...

          Show
          Jérôme Mouneyrac added a comment - Hi, I've been testing the My Moodle app with a LDAP server (OpenDS that I installed on my local machine) and it works. Reading the code, the current implementation is already generic. Could everybody having the issue tell: 1- if you can use the app with manual user (if you can't, then CAS/LDAP is not the issue, it's probably a misconfig or different bug) 2- the authentication protocol that doesn't work: LDAP / CAS / ...
          Hide
          Dan Poltawski added a comment -

          Hi,

          Sorry for jumping in on this issue - I am wondering if this is being thought of in a general sense of a single sign on system which does not authenticate with a username/password? e.g. shibboleth

          The sign in would need to be done in a web browser and then some sort of 'authenticated' token would need to be passed to the mobile app. I'd love to discuss this as I have just an example of this and some time to work on it.

          thanks,
          dan

          Show
          Dan Poltawski added a comment - Hi, Sorry for jumping in on this issue - I am wondering if this is being thought of in a general sense of a single sign on system which does not authenticate with a username/password? e.g. shibboleth The sign in would need to be done in a web browser and then some sort of 'authenticated' token would need to be passed to the mobile app. I'd love to discuss this as I have just an example of this and some time to work on it. thanks, dan
          Hide
          Matt Jenner added a comment -

          Same as Dan - we're using Shibboleth too (or planning to for moving to M2) and we would hate to miss out on the mobile app.

          Should there be a separate ticket for Shibboleth/SSO mobile auth?

          Show
          Matt Jenner added a comment - Same as Dan - we're using Shibboleth too (or planning to for moving to M2) and we would hate to miss out on the mobile app. Should there be a separate ticket for Shibboleth/SSO mobile auth?
          Hide
          Drew Blessing added a comment - - edited

          In response to several others above - Yes, fall back to LDAP would technically work. However, we are not using SSL on our Moodle sites (> than 100 sites) because we use SSO. We cannot possibly allow our users to authenticate directly to Moodle using LDAP or we would have major security issues. I would rather see the app pop a window, allow the user to authenticate with our SSO server, then grab the ticket and drop them back in to the app. Please consider this. Thanks.

          Show
          Drew Blessing added a comment - - edited In response to several others above - Yes, fall back to LDAP would technically work. However, we are not using SSL on our Moodle sites (> than 100 sites) because we use SSO. We cannot possibly allow our users to authenticate directly to Moodle using LDAP or we would have major security issues. I would rather see the app pop a window, allow the user to authenticate with our SSO server, then grab the ticket and drop them back in to the app. Please consider this. Thanks.
          Hide
          Daniel M. Zimmerman added a comment -

          I'd also like to see support for SSO... I use the university's pubcookie setup for authentication on my Moodle installation, and of course the mobile app does not work with that sort of setup yet.

          Show
          Daniel M. Zimmerman added a comment - I'd also like to see support for SSO... I use the university's pubcookie setup for authentication on my Moodle installation, and of course the mobile app does not work with that sort of setup yet.
          Hide
          Mark Davis added a comment -

          I'd also like support for SSO. We use SSO instead of SSL as well for our Moodle sites.

          Show
          Mark Davis added a comment - I'd also like support for SSO. We use SSO instead of SSL as well for our Moodle sites.
          Hide
          Jérôme Mouneyrac added a comment -

          Increasing the priority related to the number of votes.

          Show
          Jérôme Mouneyrac added a comment - Increasing the priority related to the number of votes.
          Hide
          Pasi Häkkinen added a comment -

          Shibboleth/SAML2 SSO is widely used in Finnish universities and polytechnics, so SSO support is crucial for any mobile Moodle solution in our point of view. SSO works for example with Adobe Connect Mobile app, so it is doable I think (authentication with web browser, app kicks in after that).

          Show
          Pasi Häkkinen added a comment - Shibboleth/SAML2 SSO is widely used in Finnish universities and polytechnics, so SSO support is crucial for any mobile Moodle solution in our point of view. SSO works for example with Adobe Connect Mobile app, so it is doable I think (authentication with web browser, app kicks in after that).
          Hide
          Jérôme Mouneyrac added a comment -

          Assigning to Juan, we would need to test CAS/LDAP work in Moodle Mobile.

          Show
          Jérôme Mouneyrac added a comment - Assigning to Juan, we would need to test CAS/LDAP work in Moodle Mobile.
          Hide
          Juan Leyva added a comment -

          Jerome, this is related to https://tracker.moodle.org/browse/MDL-36114 also?

          In any case, if anyone can provide a clean Moodle 2.4 installation with the Mobile service enabled and a couple of username/password for CAS/LDAP I will happy to test it

          Regards

          Show
          Juan Leyva added a comment - Jerome, this is related to https://tracker.moodle.org/browse/MDL-36114 also? In any case, if anyone can provide a clean Moodle 2.4 installation with the Mobile service enabled and a couple of username/password for CAS/LDAP I will happy to test it Regards
          Hide
          Paul Vaughan added a comment -

          Would love to see Shibboleth auth added to the mobile app. We run three separate Moodles with Shibboleth SSO enabled on two and regular Moodle signup/auth on the third. Shibboleth does not cache the user's password in the Moodle database, so we cannot auth against it directly. (But strangely, when I attempt to log in, I get 'username not found in database', which after double-checking, it definitely is.)

          Show
          Paul Vaughan added a comment - Would love to see Shibboleth auth added to the mobile app. We run three separate Moodles with Shibboleth SSO enabled on two and regular Moodle signup/auth on the third. Shibboleth does not cache the user's password in the Moodle database, so we cannot auth against it directly. (But strangely, when I attempt to log in, I get 'username not found in database', which after double-checking, it definitely is.)
          Hide
          Jérôme Mouneyrac added a comment -

          Juan we have a VM with Moodle and LDAP installed at HQ. We also may have one with Shibboleth, I'll have a look tomorrow (I'm at home now). Assigning this issue to you.

          Show
          Jérôme Mouneyrac added a comment - Juan we have a VM with Moodle and LDAP installed at HQ. We also may have one with Shibboleth, I'll have a look tomorrow (I'm at home now). Assigning this issue to you.
          Hide
          Juan Leyva added a comment - - edited

          As far as I see there are three ways for solving this:

          • MDL-36114 +1 For this one, add a new method in auth plugins for automatically log-in the user in the remote SSO site. In Shibboleth we can do that using a curl call to the Apache protected directory. This method will be caled by login/token.php (the login page that uses the mobile app).
            I don't know if this can be generic, but some config options may be provided: SSO POST url, username field name, password field name, additional fields/params.. and of course, the expected response for success or failure
          • Custom Moodle Mobile plugin. A plugin that obtains a valid user token. It can call a custom WS inside your Moodle installation or another remote WS or similar for getting a valid Moodle token for the user.
          • Custom auth plugin that implements user_authenticated_hook (This method is called from authenticate_user_login() for all enabled auth plugins) so we can inject custom code via this plugin. This is like the previous one but at Moodle side. You have to implement the logic to validate the user and then generate a valid Moodle token for the user.
          Show
          Juan Leyva added a comment - - edited As far as I see there are three ways for solving this: MDL-36114 +1 For this one, add a new method in auth plugins for automatically log-in the user in the remote SSO site. In Shibboleth we can do that using a curl call to the Apache protected directory. This method will be caled by login/token.php (the login page that uses the mobile app). I don't know if this can be generic, but some config options may be provided: SSO POST url, username field name, password field name, additional fields/params.. and of course, the expected response for success or failure Custom Moodle Mobile plugin. A plugin that obtains a valid user token. It can call a custom WS inside your Moodle installation or another remote WS or similar for getting a valid Moodle token for the user. Custom auth plugin that implements user_authenticated_hook (This method is called from authenticate_user_login() for all enabled auth plugins) so we can inject custom code via this plugin. This is like the previous one but at Moodle side. You have to implement the logic to validate the user and then generate a valid Moodle token for the user.
          Hide
          Chad Stachowicz added a comment -

          May I ask what the state of this is, and if I can help? This renders having a mobile app pretty useless if the school uses SSO.

          Chad

          Show
          Chad Stachowicz added a comment - May I ask what the state of this is, and if I can help? This renders having a mobile app pretty useless if the school uses SSO. Chad
          Hide
          Juan Leyva added a comment -

          Hi Chad,

          which type of SSO are you using? LDAP or CAS?

          You can help us providing a test user in your site, you can contact directly to me at jleyva at cvaconsulting.com

          Regards

          Show
          Juan Leyva added a comment - Hi Chad, which type of SSO are you using? LDAP or CAS? You can help us providing a test user in your site, you can contact directly to me at jleyva at cvaconsulting.com Regards
          Hide
          Chad Stachowicz added a comment -

          Juan,

          I appreciate you responding. I have sent you an email from cstachowicz@mindsmesh.com with the credentials and information. As an FYI the SSO we are using is shibboleth.

          Chad

          Show
          Chad Stachowicz added a comment - Juan, I appreciate you responding. I have sent you an email from cstachowicz@mindsmesh.com with the credentials and information. As an FYI the SSO we are using is shibboleth. Chad
          Hide
          Juan Leyva added a comment -

          Hi,

          Chad thanks for providing credentials for testing a Shibboleth installation.

          After spending some time evaluating different systems I think that the only way to allow the app to connect with systems that performs SSO is developing a generic auth plugin that can emulate the SSO performed by a real user, so my plan is:

          • Create a new generic auth plugin (mobilesso)
          • This plugin should work initially for any SSO method that works sending cookies
          • Support for different SSO methods (values in the Server headers, etc...) will be added in further steps
          • The plugin will detect when a user is trying to authenticate using Moodle Mobile (the auth entry point for this case is login/token.php instead login/index.php so I can detect this easily)
          • The plugin can be enabled or disabled at any time
          • In the plugin settings an admin must indicate:
            • The remote system login URL where to launch a GET or POST request
            • The type of request POST or GET
            • The POST/GET values to be send in format: username= {username}&password={pasword}&extradata=custominfo {username}

              or

              {password}

              indicates the original username and password submitted by the user

            • The method used for validate the login, in the first version the only method will be "Cookies"
            • The name of the cookie expected, if this cookie is sent by the remote system we understand that the login was successfull

          If anyone want to help, the best way is providing test users in your sites that uses SSO, at jleyva at cvaconsulting.com

          Regards

          Show
          Juan Leyva added a comment - Hi, Chad thanks for providing credentials for testing a Shibboleth installation. After spending some time evaluating different systems I think that the only way to allow the app to connect with systems that performs SSO is developing a generic auth plugin that can emulate the SSO performed by a real user, so my plan is: Create a new generic auth plugin (mobilesso) This plugin should work initially for any SSO method that works sending cookies Support for different SSO methods (values in the Server headers, etc...) will be added in further steps The plugin will detect when a user is trying to authenticate using Moodle Mobile (the auth entry point for this case is login/token.php instead login/index.php so I can detect this easily) The plugin can be enabled or disabled at any time In the plugin settings an admin must indicate: The remote system login URL where to launch a GET or POST request The type of request POST or GET The POST/GET values to be send in format: username= {username}&password={pasword}&extradata=custominfo {username} or {password} indicates the original username and password submitted by the user The method used for validate the login, in the first version the only method will be "Cookies" The name of the cookie expected, if this cookie is sent by the remote system we understand that the login was successfull If anyone want to help, the best way is providing test users in your sites that uses SSO, at jleyva at cvaconsulting.com Regards
          Hide
          Chad Stachowicz added a comment -

          Juan,

          This sounds fantastic and I am glad you were able to get some help from my example credentials. I will eagerly keep following this ticket.

          Cheers,

          Chad

          Show
          Chad Stachowicz added a comment - Juan, This sounds fantastic and I am glad you were able to get some help from my example credentials. I will eagerly keep following this ticket. Cheers, Chad
          Hide
          Dan Small added a comment -

          If the problem is that the token.php file does not utilise the loginpage_hook() function
          implemented by some Moodle auth plugins, then this change should fix it.

          /* Start of change.

          ABOUT
          Change to the Moodle login/token.php file needed in order to utilise loginpage_hook() function
          implemented by some Moodle auth plugins.
          Change by Sheridan "Dan" Small, University of Exeter <s.j.small@exeter.ac.uk>.
          License for this change http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.

          TESTING
          This has been tested on Moodle 2.4.5 using an auth plugin that supplies fake form data.
          However it should work with a plugin providing a full user but this is, at present, untested.
          (Please let me know if you have tested this code on other versions of Moodle and/or with a plugin
          providing a full user.)

          INSTRUCTIONS
          I'm reluctant to change Moodle core files myself so copy the Moodle login/token.php file to create
          a new file e.g. uoetoken.php.
          Find the 5 lines of code below (line 39 to 43 in Moodle 2.4.5) in the new file and replace it
          with the entire contents of this file.

          $username = trim(textlib::strtolower($username));
          if (is_restored_user($username))

          { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); }

          $user = authenticate_user_login($username, $password);

          USAGE
          Get a cookie or whatever you need for your auth module and visit your new file URL e.g.
          https://yourmoodle.ac.uk/login/uoetoken.php?username=dummy&password=noway&service=servicename
          (use dummy values for username and password if they are not needed for your auth plugin).
          */

          $frm = false;
          $user = false;
          $authsequence = get_enabled_auth_plugins(true); // auths, in sequence
          foreach ($authsequence as $authname)

          { debugging("Looping through authenticaton plugins: $authname", DEBUG_DEVELOPER); $authplugin = get_auth_plugin($authname); $authplugin->loginpage_hook(); }

          if ($user !== false or $frm !== false or $errormsg !== '') {
          // Some auth plugin already supplied full user, fake form data or prevented user login with error message.
          debugging("Auth plugin supplied full user, fake form data or prevented user login with error message.", DEBUG_DEVELOPER);
          if ($user !== false && !empty($user->username) && !(isset($errormsg) && !empty($errormsg))) {
          debugging("Auth plugin supplied full user $user->username.", DEBUG_DEVELOPER);
          $username = trim(textlib::strtolower($user->username));
          if (is_restored_user($username))

          { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); }
          } else if ($user === false && $frm !== false && !(isset($errormsg) && !empty($errormsg))) {
          debugging("Auth plugin supplied fake form data $frm->username.", DEBUG_DEVELOPER);
          $username = trim(textlib::strtolower($frm->username));
          debugging("username: $username", DEBUG_DEVELOPER);
          if (is_restored_user($username)) { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); }

          $user = get_complete_user_data('username', $username, $CFG->mnet_localhost_id);
          } else

          { # This should really throw a new exception rather than re-use an existing one. throw new moodle_exception('usernotallowed', 'webservice', '', $serviceshortname); }

          } else {
          $username = trim(textlib::strtolower($username));
          if (is_restored_user($username))

          { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); }

          $user = authenticate_user_login($username, $password);
          }
          /* End of change */

          Show
          Dan Small added a comment - If the problem is that the token.php file does not utilise the loginpage_hook() function implemented by some Moodle auth plugins, then this change should fix it. /* Start of change. ABOUT Change to the Moodle login/token.php file needed in order to utilise loginpage_hook() function implemented by some Moodle auth plugins. Change by Sheridan "Dan" Small, University of Exeter <s.j.small@exeter.ac.uk>. License for this change http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later. TESTING This has been tested on Moodle 2.4.5 using an auth plugin that supplies fake form data. However it should work with a plugin providing a full user but this is, at present, untested. (Please let me know if you have tested this code on other versions of Moodle and/or with a plugin providing a full user.) INSTRUCTIONS I'm reluctant to change Moodle core files myself so copy the Moodle login/token.php file to create a new file e.g. uoetoken.php. Find the 5 lines of code below (line 39 to 43 in Moodle 2.4.5) in the new file and replace it with the entire contents of this file. $username = trim(textlib::strtolower($username)); if (is_restored_user($username)) { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); } $user = authenticate_user_login($username, $password); USAGE Get a cookie or whatever you need for your auth module and visit your new file URL e.g. https://yourmoodle.ac.uk/login/uoetoken.php?username=dummy&password=noway&service=servicename (use dummy values for username and password if they are not needed for your auth plugin). */ $frm = false; $user = false; $authsequence = get_enabled_auth_plugins(true); // auths, in sequence foreach ($authsequence as $authname) { debugging("Looping through authenticaton plugins: $authname", DEBUG_DEVELOPER); $authplugin = get_auth_plugin($authname); $authplugin->loginpage_hook(); } if ($user !== false or $frm !== false or $errormsg !== '') { // Some auth plugin already supplied full user, fake form data or prevented user login with error message. debugging("Auth plugin supplied full user, fake form data or prevented user login with error message.", DEBUG_DEVELOPER); if ($user !== false && !empty($user->username) && !(isset($errormsg) && !empty($errormsg))) { debugging("Auth plugin supplied full user $user->username.", DEBUG_DEVELOPER); $username = trim(textlib::strtolower($user->username)); if (is_restored_user($username)) { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); } } else if ($user === false && $frm !== false && !(isset($errormsg) && !empty($errormsg))) { debugging("Auth plugin supplied fake form data $frm->username.", DEBUG_DEVELOPER); $username = trim(textlib::strtolower($frm->username)); debugging("username: $username", DEBUG_DEVELOPER); if (is_restored_user($username)) { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); } $user = get_complete_user_data('username', $username, $CFG->mnet_localhost_id); } else { # This should really throw a new exception rather than re-use an existing one. throw new moodle_exception('usernotallowed', 'webservice', '', $serviceshortname); } } else { $username = trim(textlib::strtolower($username)); if (is_restored_user($username)) { throw new moodle_exception('restoredaccountresetpassword', 'webservice'); } $user = authenticate_user_login($username, $password); } /* End of change */
          Hide
          Dan Small added a comment -

          Complete file with change Moodle 2.4.5.

          Show
          Dan Small added a comment - Complete file with change Moodle 2.4.5.
          Hide
          Dan Trockman added a comment -

          We use a 3rd party sso (ssoeasy - easyconnect) to connect to our AD. No luck in using the newest mobile with newest moodle. Any hope for this to work in the future? All systems are go for manual test users.

          Show
          Dan Trockman added a comment - We use a 3rd party sso (ssoeasy - easyconnect) to connect to our AD. No luck in using the newest mobile with newest moodle. Any hope for this to work in the future? All systems are go for manual test users.
          Hide
          Brian King added a comment -

          Many higher education institutions in Switzerland use Shibboleth as a SSO solution. It would be great to see this move forward.

          Is there any WIP code anyplace, or is this still in the implementation idea phase?

          Show
          Brian King added a comment - Many higher education institutions in Switzerland use Shibboleth as a SSO solution. It would be great to see this move forward. Is there any WIP code anyplace, or is this still in the implementation idea phase?
          Hide
          David Sturrock added a comment -

          We use SAML 2 plugin to SSO via an ADFS service and are very keen to support Mobile app access. Is there anything we can do to support resolving this issue?

          Show
          David Sturrock added a comment - We use SAML 2 plugin to SSO via an ADFS service and are very keen to support Mobile app access. Is there anything we can do to support resolving this issue?
          Hide
          Steve Massicotte added a comment -

          Any new with that issue ? We are using CAS and we want to use the Moodle web service in our portal. We need a way to make token.php know that the person is already authenticate with CAS. For the same reason we cannot use the Moodle mobile app.

          I will try the code that Dan Small as submit.

          Show
          Steve Massicotte added a comment - Any new with that issue ? We are using CAS and we want to use the Moodle web service in our portal. We need a way to make token.php know that the person is already authenticate with CAS. For the same reason we cannot use the Moodle mobile app. I will try the code that Dan Small as submit.
          Hide
          Goran Josic added a comment -

          I'm really interested in this plugin.

          I have developed a AAI moodle authentication plugin. You can check the code here:

          https://github.com/arael/Moodle_MobileAAI_auth_plugin

          Right now it is ad hoc for my university and it is intended for the mobile access.

          If you think it could be useful and should be integrated in your authentication plugin I'm willing to re-factor the code and help covering the AAI authentication.

          Show
          Goran Josic added a comment - I'm really interested in this plugin. I have developed a AAI moodle authentication plugin. You can check the code here: https://github.com/arael/Moodle_MobileAAI_auth_plugin Right now it is ad hoc for my university and it is intended for the mobile access. If you think it could be useful and should be integrated in your authentication plugin I'm willing to re-factor the code and help covering the AAI authentication.
          Hide
          Juan Leyva added a comment -

          I just created MDL-44541, I think the best way to solve this issue is requesting a new auth hook method so we can create plugins for handling authentication of SSO/External auth systems.

          Notice that there is not a valid solution for all type of authentication since they depend on external systems that the mobile app can't access.

          With this new hook, I will be able to implement plugins for some of the existing cases, but in all the cases it will required a "invisible" login, I mean, the user will not be prompted to enter their credentials in a different place in the mobile app, the plugin will be responsible of this process.

          Steps:
          The user open Moodle Mobile, enter his credentials
          The custom auth plugin (that implements the hook) handle this request, the plugin has the username and password and has to validate this credential against and LDAP or another different system (this will require custom implementations in some cases, for CAS I suppose we can simple bin to LDAP?)
          The plugin returns that the user is authenticated, so a user token can be created or returned

          Show
          Juan Leyva added a comment - I just created MDL-44541 , I think the best way to solve this issue is requesting a new auth hook method so we can create plugins for handling authentication of SSO/External auth systems. Notice that there is not a valid solution for all type of authentication since they depend on external systems that the mobile app can't access. With this new hook, I will be able to implement plugins for some of the existing cases, but in all the cases it will required a "invisible" login, I mean, the user will not be prompted to enter their credentials in a different place in the mobile app, the plugin will be responsible of this process. Steps: The user open Moodle Mobile, enter his credentials The custom auth plugin (that implements the hook) handle this request, the plugin has the username and password and has to validate this credential against and LDAP or another different system (this will require custom implementations in some cases, for CAS I suppose we can simple bin to LDAP?) The plugin returns that the user is authenticated, so a user token can be created or returned
          Hide
          Juan Leyva added a comment -

          Hi,

          just a question for those who can't use Moodle Mobile:

          If you can configure in your auth plugin a fallback auth plugin, your problem will be solved?

          I mean, say you have CAS or Shibbolet configured, and there you has an UI for adding another auth method (yet configured in Moodle) if the previous fails (ldap, database) so if a user can't log-in with CAS then the credentials are checked again against a different system (ldap or external database) to authenticate the user

          do you think this may solve your problem?

          Regards

          Show
          Juan Leyva added a comment - Hi, just a question for those who can't use Moodle Mobile: If you can configure in your auth plugin a fallback auth plugin, your problem will be solved? I mean, say you have CAS or Shibbolet configured, and there you has an UI for adding another auth method (yet configured in Moodle) if the previous fails (ldap, database) so if a user can't log-in with CAS then the credentials are checked again against a different system (ldap or external database) to authenticate the user do you think this may solve your problem? Regards
          Hide
          Brian King added a comment - - edited

          Hi Juan,

          from my experience, no, a fallback mechanism would not be a solution. As used in the swiss university system, anyway, Shibboleth passwords are centralized (managed by an organisation called SWITCH) and there's no way to have a copy of those or validate the login at SWITCH with another mechanism.

          And no one want to manage a second, potentially different password for the users - it would confuse the users, and lead to lots of support desk issues.

          Show
          Brian King added a comment - - edited Hi Juan, from my experience, no, a fallback mechanism would not be a solution. As used in the swiss university system, anyway, Shibboleth passwords are centralized (managed by an organisation called SWITCH) and there's no way to have a copy of those or validate the login at SWITCH with another mechanism. And no one want to manage a second, potentially different password for the users - it would confuse the users, and lead to lots of support desk issues.
          Hide
          David Sturrock added a comment -

          The fallback option could work in our situation - we fall back to radius which queries the same AD account.

          Show
          David Sturrock added a comment - The fallback option could work in our situation - we fall back to radius which queries the same AD account.
          Hide
          Mark Davis added a comment -

          That would not work for us either as we also use CAS and thus Moodle doesn't have any stored alternative/backup.

          Show
          Mark Davis added a comment - That would not work for us either as we also use CAS and thus Moodle doesn't have any stored alternative/backup.
          Hide
          Juan Leyva added a comment -

          Hi Mark Davis, CAS doesn't use LDAP as backend? Sorry If I'm wrong, I'm not very familiar with CAS

          Show
          Juan Leyva added a comment - Hi Mark Davis , CAS doesn't use LDAP as backend? Sorry If I'm wrong, I'm not very familiar with CAS
          Hide
          Mark Davis added a comment -

          No Juan, it does not (have to).

          Our configuration does not use nor require LDAP.

          Show
          Mark Davis added a comment - No Juan, it does not (have to). Our configuration does not use nor require LDAP.
          Hide
          Martin Dougiamas added a comment - - edited

          After some discussion here my current understanding of the "proper way" to fix this looks like this:

          1. Modify app to chage login page to just ask for site address alone.
          2. Our app contacts the site and establishes if a) Moodle mobile is not supported, b) it's an older Moodle site or c) it's a newer Moodle site supporting SSO for mobile.
            • a) Print a message and return to 1)
            • b) We get the username/password and login as we do now and get a token. SSO is not supported.
            • c) We open a web browser and go to the Moodle login page with a new parameter that tells Moodle it's inside the Mobile app.
          3. In this last case, Moodle will redirect to the SSO page, then return to Moodle login page afterwards, and then the login page will know how to pass a token back to the mobile app.
          4. The mobile app uses the token for communications.

          How does this sound?

          It would mean:

          On Moodle:

          • update the login page and perhaps backport to some recent versions.
          • decide a good way to distinguish between b) and c) reliably without any authentication

          On Mobile app:

          • Reorganise login pages as described
          Show
          Martin Dougiamas added a comment - - edited After some discussion here my current understanding of the "proper way" to fix this looks like this: Modify app to chage login page to just ask for site address alone. Our app contacts the site and establishes if a) Moodle mobile is not supported, b) it's an older Moodle site or c) it's a newer Moodle site supporting SSO for mobile. a) Print a message and return to 1) b) We get the username/password and login as we do now and get a token. SSO is not supported. c) We open a web browser and go to the Moodle login page with a new parameter that tells Moodle it's inside the Mobile app. In this last case, Moodle will redirect to the SSO page, then return to Moodle login page afterwards, and then the login page will know how to pass a token back to the mobile app. The mobile app uses the token for communications. How does this sound? It would mean: On Moodle: update the login page and perhaps backport to some recent versions. decide a good way to distinguish between b) and c) reliably without any authentication On Mobile app: Reorganise login pages as described
          Hide
          Juan Leyva added a comment -

          Hi Martin,

          some comments:

          • If we need to check that Moodle Mobile is/is not supported (and also SSO auth methods) prior to user authentication we'd need to create a public WS displaying this information. This means that it will be possible to any non-authenticated user to retrieve configuration information of the Moodle installation.
            Also, the current WS infrastructure requires a valid user token, so the new WS should be placed outside the current WS area
          • The login page must pass the token back to the mobile app in a safe mode using the postMessage method https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage (It will require some changes in the Moodle loginpage) Notice that for doing that, we need to open the Moodle installation using the InAppBrowser that comes with Phonegap (so we can do a window.open and get a reference to the new popup window in order to allow postMessage to work between the app and Moodle)

          So my only concern is about security/privacy of Moodle settings, we will create a way of getting Moodle settings for non-authenticated user (some that currently is not possible)

          Show
          Juan Leyva added a comment - Hi Martin, some comments: If we need to check that Moodle Mobile is/is not supported (and also SSO auth methods) prior to user authentication we'd need to create a public WS displaying this information. This means that it will be possible to any non-authenticated user to retrieve configuration information of the Moodle installation. Also, the current WS infrastructure requires a valid user token, so the new WS should be placed outside the current WS area The login page must pass the token back to the mobile app in a safe mode using the postMessage method https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage (It will require some changes in the Moodle loginpage) Notice that for doing that, we need to open the Moodle installation using the InAppBrowser that comes with Phonegap (so we can do a window.open and get a reference to the new popup window in order to allow postMessage to work between the app and Moodle) So my only concern is about security/privacy of Moodle settings, we will create a way of getting Moodle settings for non-authenticated user (some that currently is not possible)
          Hide
          Pasi Häkkinen added a comment -

          Have you considered using web browser for authentication also in mobile devices? Something like this should work: https://developers.google.com/accounts/docs/MobileApps

          Show
          Pasi Häkkinen added a comment - Have you considered using web browser for authentication also in mobile devices? Something like this should work: https://developers.google.com/accounts/docs/MobileApps
          Hide
          Dan Poltawski added a comment -

          The only concern is step 4 and security of this token, ideally we should be using an existing protocol for this flow.

          Regarding Juans comment:

          The login page must pass the token back to the mobile app in a safe mode using the postMessage method.

          It doesn't need to, i'm envisaging a customisable URI scheme and a standard browser.

          Show
          Dan Poltawski added a comment - The only concern is step 4 and security of this token, ideally we should be using an existing protocol for this flow. Regarding Juans comment: The login page must pass the token back to the mobile app in a safe mode using the postMessage method. It doesn't need to, i'm envisaging a customisable URI scheme and a standard browser.
          Hide
          Dan Poltawski added a comment - - edited

          Here is an an attempt demonstrate what I mean (ignore the urls and things - just trying to demonstrate the point).

          app does: GET http//mymooodle/auth/mobile_login_status
          
          if status = 200:
              open url http//mymooodle/login/?mobileurl=org.moodle.app://login
              (SSO stuff happens, potentially going to other servers in the browser, but eventually ending in a moodle session like happens normally).
              Moodle redirects to mobileurl received with token added (e.g. org.moodle.app://login?token=foo )
          
          
          if status = 401: 
              Show page saying Moodle mobile is not supported on this.
          
          if status = 404:
              Fall back to what we have now (ugly but ncessary for BC)
          

          Some notes:

          • It occurs to me whilst I wrote this, that it will be advantageous to have a real browser rather than in built one for maximum compatibility. I'm sure there are some SSO systems which will use client certificates or advanced features which will be better using the standard browser.
          • We only expose whether the 'mobile login' is enabled, but this is't going to be private information and you should think of it beyond our mobile app. If done right, this can be used by other client applications.
          Show
          Dan Poltawski added a comment - - edited Here is an an attempt demonstrate what I mean (ignore the urls and things - just trying to demonstrate the point). app does: GET http //mymooodle/auth/mobile_login_status if status = 200: open url http //mymooodle/login/?mobileurl=org.moodle.app://login (SSO stuff happens, potentially going to other servers in the browser, but eventually ending in a moodle session like happens normally). Moodle redirects to mobileurl received with token added (e.g. org.moodle.app: //login?token=foo ) if status = 401: Show page saying Moodle mobile is not supported on this . if status = 404: Fall back to what we have now (ugly but ncessary for BC) Some notes: It occurs to me whilst I wrote this, that it will be advantageous to have a real browser rather than in built one for maximum compatibility. I'm sure there are some SSO systems which will use client certificates or advanced features which will be better using the standard browser. We only expose whether the 'mobile login' is enabled, but this is't going to be private information and you should think of it beyond our mobile app. If done right, this can be used by other client applications.
          Hide
          Martin Dougiamas added a comment -

          Sounds good to me, Dan

          Show
          Martin Dougiamas added a comment - Sounds good to me, Dan
          Hide
          Juan Leyva added a comment - - edited

          Hi Dan,

          yes, custom URL schemes sounds like the natural choice for this case but, unfortunately, it has some limitations (so that is the reason I proposed a "standard" solution, not platform dependent):

          • It's only supported natively by Phonegap for iOs apps
          • We are planning to add new platoforms (like Firefox Os, win8) and there is not support for this type of schemes for that platforms in Phonegap
          • The support for custom URL schemes in iOs apps seems a little bit buggy right now (I did some tests a couple of months ago). It works well when the app is closed but not when is frozen in the background (seems to ignore the events attached because is already open)

          Edited: I've found a Phonegap plugin (added some weeks ago) that implement URL schemes for both Android and iOs, I can make some tests to see if it's suitable:

          https://build.phonegap.com/plugins/433

          Show
          Juan Leyva added a comment - - edited Hi Dan, yes, custom URL schemes sounds like the natural choice for this case but, unfortunately, it has some limitations (so that is the reason I proposed a "standard" solution, not platform dependent): It's only supported natively by Phonegap for iOs apps We are planning to add new platoforms (like Firefox Os, win8) and there is not support for this type of schemes for that platforms in Phonegap The support for custom URL schemes in iOs apps seems a little bit buggy right now (I did some tests a couple of months ago). It works well when the app is closed but not when is frozen in the background (seems to ignore the events attached because is already open) Edited: I've found a Phonegap plugin (added some weeks ago) that implement URL schemes for both Android and iOs, I can make some tests to see if it's suitable: https://build.phonegap.com/plugins/433
          Hide
          Jason Howe added a comment -

          Just weighing in here. We just started looking at the Moodle Mobile app the other day. Our moodle is also behind an SSO system (Shibboleth). What's more is there are some classes of users we require use 2-factor authentication into the IDP. I think a redirect using the standard browser here to get the right ticket/cookie etc back is the right way to go.

          Show
          Jason Howe added a comment - Just weighing in here. We just started looking at the Moodle Mobile app the other day. Our moodle is also behind an SSO system (Shibboleth). What's more is there are some classes of users we require use 2-factor authentication into the IDP. I think a redirect using the standard browser here to get the right ticket/cookie etc back is the right way to go.
          Hide
          Juan Leyva added a comment -

          Well, after some reading and testing I've found that we have 4 alternatives:

          • InAppBrowser
            This is a full feature browser we can control from the mobile app. We can open it, and get notified when the url change, we can also inject javascript. So, we can know when a SSO process ends (based on the url change) and inject javascript for getting the token from the source code or just getting the token from the endpoint sso url (if the token is in the get parameters)
          • Oauth1 or OAuth2: This method implicates also using the InAppBrowser. We can launch an OAuth process and we can detect when the callback url is loaded in the appbrowser and retrieve from there (get parameters) the access token (the token will be a valid Moodle webservices token) OAuth1 seems more natural for this approach because OAuth2 refresh tokens may not apply here...

          In any case, we will need to implement the REST service for indicating if the app supports SSO or not

          Martin, I have a question: are we going to force the user to always login in Moodle in the browser? (if the Moodle instance supports this new feature)
          Most of the sites doesn't use SSO and seems more natural to directly introduce the url, username and password directly in the app (how it works currently)

          I think we must force only login in the browser in special cases (like SSO), so I suggest to first enter the URL and only open the browser with the Moodle login page in case of SSO (Shibbolet or CAS)

          Show
          Juan Leyva added a comment - Well, after some reading and testing I've found that we have 4 alternatives: Custom URL schemes As pointed by Dan seems a clever way for opening the app once we have a token: See comment https://tracker.moodle.org/browse/MOBILE-113?focusedCommentId=277963&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-277963 PostMessage https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage but I think it may have security problems since we are running the HTML5 under file:// protocol We can communicate a browser instance and the Mobile app using events. InAppBrowser This is a full feature browser we can control from the mobile app. We can open it, and get notified when the url change, we can also inject javascript. So, we can know when a SSO process ends (based on the url change) and inject javascript for getting the token from the source code or just getting the token from the endpoint sso url (if the token is in the get parameters) Oauth1 or OAuth2: This method implicates also using the InAppBrowser. We can launch an OAuth process and we can detect when the callback url is loaded in the appbrowser and retrieve from there (get parameters) the access token (the token will be a valid Moodle webservices token) OAuth1 seems more natural for this approach because OAuth2 refresh tokens may not apply here... In any case, we will need to implement the REST service for indicating if the app supports SSO or not Martin, I have a question: are we going to force the user to always login in Moodle in the browser? (if the Moodle instance supports this new feature) Most of the sites doesn't use SSO and seems more natural to directly introduce the url, username and password directly in the app (how it works currently) I think we must force only login in the browser in special cases (like SSO), so I suggest to first enter the URL and only open the browser with the Moodle login page in case of SSO (Shibbolet or CAS)
          Hide
          Dan Poltawski added a comment -

          Juan, is it not possible to support Custom URL schemes in the InAppBrowser too? It doesn't seem to me like we need to do the javascript approach for that.

          I think having at least the option of using a 'standard' browser (my custom url schemes option) is useful and is going to be the option which has widest support. As I mentioned in an earlier comment - there might be advanced technologies such as client certificates which the native browser supports that an InAppBrowser might not, or might not immediately. Another example, I use 1Password, I could login to moodle using the 1password app and then sent the moodle mobile app. By using the url scheme we don't exclude any crazy enterprise setup.

          Show
          Dan Poltawski added a comment - Juan, is it not possible to support Custom URL schemes in the InAppBrowser too? It doesn't seem to me like we need to do the javascript approach for that. I think having at least the option of using a 'standard' browser (my custom url schemes option) is useful and is going to be the option which has widest support. As I mentioned in an earlier comment - there might be advanced technologies such as client certificates which the native browser supports that an InAppBrowser might not, or might not immediately. Another example, I use 1Password, I could login to moodle using the 1password app and then sent the moodle mobile app. By using the url scheme we don't exclude any crazy enterprise setup.
          Hide
          Juan Leyva added a comment - - edited

          Hi Dan,

          inAppBrowser is in fact, a native browser with supports everything. I've seen implementations of OAuth2 for Google APIs using this browser.

          But in any case, I also prefer the URL schemes approach. May initial concerns were the missing native support in Phonegap but I think we can use this plugin submitted a few weeks ago https://build.phonegap.com/plugins/433 and also it seems that firefox Os (we're working for support it as new platform) supports URL schemes using HTML5 native code (no need to Phonegap plugin)

          Dan, how do you think I should implement the "service" that returns the mobile status of the app? It should return if mobile is not enabled, auth type is SSO, auth type is normal, etc...

          In your previous comment you used HTTP status codes as example

          Show
          Juan Leyva added a comment - - edited Hi Dan, inAppBrowser is in fact, a native browser with supports everything. I've seen implementations of OAuth2 for Google APIs using this browser. But in any case, I also prefer the URL schemes approach. May initial concerns were the missing native support in Phonegap but I think we can use this plugin submitted a few weeks ago https://build.phonegap.com/plugins/433 and also it seems that firefox Os (we're working for support it as new platform) supports URL schemes using HTML5 native code (no need to Phonegap plugin) Dan, how do you think I should implement the "service" that returns the mobile status of the app? It should return if mobile is not enabled, auth type is SSO, auth type is normal, etc... In your previous comment you used HTTP status codes as example
          Hide
          Dan Poltawski added a comment -

          I am not intimately familiar with the web service framework enough to know if we could support it as a standard webservice when it needs to an unauthenticated call (otherwise it could just be a simple new php script).

          My bigger concern is what we are going to use for the token?

          Show
          Dan Poltawski added a comment - I am not intimately familiar with the web service framework enough to know if we could support it as a standard webservice when it needs to an unauthenticated call (otherwise it could just be a simple new php script). My bigger concern is what we are going to use for the token?
          Hide
          Juan Leyva added a comment -

          Nope, it can't be a standard webservice (requires authenticated calls)

          I'm not sure if I understood correctly this phrase: "My bigger concern is what we are going to use for the token?"

          The token is the authentication token used by the Mobile app when calling Moodle WebServices
          Is the token you get usually via login/token.php (you can disable/delete these tokens in your seggins page)

          I imagine the overall process like:

          1 A user open the Mobile app, enter a Moodle instance url (mymoodle.org)
          2 mymoodle.org/auth/mobile_status.php is called as a REST service
          3 The previous URL returns that Shibbolet is used so the Mobile app notify the user that a new browser instance is going to be opened and that he should enter his credentials there
          4 A new browser instance is opened and redirected to mymoodle.org/login/index.php?sso=mobileapp
          5 A new SESSION var is setted (call_custom_url_scheme_when_user_logged)
          6 When the login process is finished and the user is redirected to Moodle frontpage, the SESSION var is checked, if exists the browser is redirected to the custom url scheme for opening the app (token is passed as a parameter) The user token may not exist, so at this moment is created (Notice that token are linked to a service, so I think in point 4 we need to indicate the service shortname)
          7 Moodle Mobile detect the custom url scheme and retrieve the token from the URL

          Show
          Juan Leyva added a comment - Nope, it can't be a standard webservice (requires authenticated calls) I'm not sure if I understood correctly this phrase: "My bigger concern is what we are going to use for the token?" The token is the authentication token used by the Mobile app when calling Moodle WebServices Is the token you get usually via login/token.php (you can disable/delete these tokens in your seggins page) I imagine the overall process like: 1 A user open the Mobile app, enter a Moodle instance url (mymoodle.org) 2 mymoodle.org/auth/mobile_status.php is called as a REST service 3 The previous URL returns that Shibbolet is used so the Mobile app notify the user that a new browser instance is going to be opened and that he should enter his credentials there 4 A new browser instance is opened and redirected to mymoodle.org/login/index.php?sso=mobileapp 5 A new SESSION var is setted (call_custom_url_scheme_when_user_logged) 6 When the login process is finished and the user is redirected to Moodle frontpage, the SESSION var is checked, if exists the browser is redirected to the custom url scheme for opening the app (token is passed as a parameter) The user token may not exist, so at this moment is created (Notice that token are linked to a service, so I think in point 4 we need to indicate the service shortname) 7 Moodle Mobile detect the custom url scheme and retrieve the token from the URL
          Hide
          Dan Poltawski added a comment -

          Hi Juan,

          Great - I am in complete agreement with the process in general.

          What I am getting at is that my concern is point 6 and the security of this token. It's equivalent to passing a username and password around, so there is a need to be cautious.

          If we were doing it with OAuth 2.0, we would return a short lived (access token) then the app would use a shared secret + the access token to make an API call to upgrade that token. It means that this token is never exposed to anywhere outside of the app. The access token doesn't provide you access anything and it also expires after 1 or 2 mins. Therefore if someone intercepts the access token they need the shared key too to do anything more and they also can not keep trying because the token expires.

          If someone intercepts our token you mention in point 6 then they have unlimited access to the web services unless the user deletes the token, right?

          NOTE: I'm not suggesting we should use Oauth 2.0 - its just the protocol I know. In fact it has major implementation difficulties in our scenario:

          • We would need some way to have a shared secret that would work on our single app with multiple Moodle installs..
          • The spec declares that the server runs on https..
          Show
          Dan Poltawski added a comment - Hi Juan, Great - I am in complete agreement with the process in general. What I am getting at is that my concern is point 6 and the security of this token. It's equivalent to passing a username and password around, so there is a need to be cautious. If we were doing it with OAuth 2.0, we would return a short lived (access token) then the app would use a shared secret + the access token to make an API call to upgrade that token. It means that this token is never exposed to anywhere outside of the app. The access token doesn't provide you access anything and it also expires after 1 or 2 mins. Therefore if someone intercepts the access token they need the shared key too to do anything more and they also can not keep trying because the token expires. If someone intercepts our token you mention in point 6 then they have unlimited access to the web services unless the user deletes the token, right? NOTE: I'm not suggesting we should use Oauth 2.0 - its just the protocol I know. In fact it has major implementation difficulties in our scenario: We would need some way to have a shared secret that would work on our single app with multiple Moodle installs.. The spec declares that the server runs on https..
          Hide
          Asaf Ohayon added a comment -

          What if we had another field for 'auth', like 'wsauth', for alternative authetication mechanisem in this case ?

          when login/token.php is accessed, this alternative authentication can be used,
          this will resolve any such issue related to webservices in general

          Show
          Asaf Ohayon added a comment - What if we had another field for 'auth', like 'wsauth', for alternative authetication mechanisem in this case ? when login/token.php is accessed, this alternative authentication can be used, this will resolve any such issue related to webservices in general
          Hide
          Asaf Ohayon added a comment -

          This will use alternative login mechanisem specified in user->wsauth,
          (must be added in the database mdl_user->wsauth)

          Show
          Asaf Ohayon added a comment - This will use alternative login mechanisem specified in user->wsauth, (must be added in the database mdl_user->wsauth)
          Hide
          Asaf Ohayon added a comment -

          I've attached the patch here, sso_mobile_auth.diff
          A field needs to be added in the database, mdl_user -> wsauth,

          when accessing login/token.php, wsauth will be used instead of auth,
          this works for me, very simple and small patch

          Show
          Asaf Ohayon added a comment - I've attached the patch here, sso_mobile_auth.diff A field needs to be added in the database, mdl_user -> wsauth, when accessing login/token.php, wsauth will be used instead of auth, this works for me, very simple and small patch

            Dates

            • Created:
              Updated:

              Development