Erik Ordway
added a comment - 14/Sep/11 12:20 AM 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.

" 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."

Patrick Pollet
added a comment - 16/Sep/11 7:43 PM 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.

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).

Jérôme Mouneyrac
added a comment - 23/Sep/11 11:32 AM 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).

Jérôme Mouneyrac
added a comment - 30/Sep/11 10:48 AM 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.

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.

J Ross Nicoll
added a comment - 30/Sep/11 10:03 PM 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.

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 / ...

Jérôme Mouneyrac
added a comment - 31/Oct/11 4:54 PM 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 / ...

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.

Dan Poltawski
added a comment - 03/Nov/11 7:04 PM 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

Matt Jenner
added a comment - 13/Dec/11 10:46 PM 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?

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.

Drew Blessing
added a comment - 22/Dec/11 12:23 PM - 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.

Daniel M. Zimmerman
added a comment - 07/Jan/12 5:46 AM 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.

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).

Pasi Häkkinen
added a comment - 05/Jun/12 8:59 PM 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).

Juan Leyva
added a comment - 17/Jan/13 8:16 AM 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

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.)

Paul Vaughan
added a comment - 12/Mar/13 9:22 AM 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.)

Jérôme Mouneyrac
added a comment - 12/Mar/13 9:37 AM 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.

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.

Juan Leyva
added a comment - 11/Apr/13 7:22 AM - 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.

Juan Leyva
added a comment - 18/Jul/13 11:30 AM 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

Chad Stachowicz
added a comment - 18/Jul/13 12:40 PM 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

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

Juan Leyva
added a comment - 24/Jul/13 10:25 AM 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

Chad Stachowicz
added a comment - 24/Jul/13 1:01 PM 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

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.

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.

Dan Trockman
added a comment - 21/Aug/13 1:33 AM 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.

Brian King
added a comment - 30/Sep/13 3:19 PM 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?

David Sturrock
added a comment - 18/Nov/13 1:23 AM 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?

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.

Steve Massicotte
added a comment - 07/Mar/14 8:23 PM 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.

Goran Josic
added a comment - 10/Mar/14 1:54 PM 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.

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

Juan Leyva
added a comment - 10/Mar/14 5:37 PM 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

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

Juan Leyva
added a comment - 13/Mar/14 12:41 PM 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

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.

Brian King
added a comment - 13/Mar/14 2:10 PM - 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.

Martin Dougiamas
added a comment - 17/Mar/14 7:12 AM - 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

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)

Juan Leyva
added a comment - 17/Mar/14 1:25 PM 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)

Pasi Häkkinen
added a comment - 17/Mar/14 1:55 PM Have you considered using web browser for authentication also in mobile devices? Something like this should work: https://developers.google.com/accounts/docs/MobileApps

Dan Poltawski
added a comment - 18/Mar/14 3:50 AM 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.

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.

Dan Poltawski
added a comment - 18/Mar/14 4:09 AM - 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.

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:

Juan Leyva
added a comment - 18/Mar/14 10:07 AM - 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

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.

Jason Howe
added a comment - 27/Mar/14 1:56 AM 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.

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)

Juan Leyva
added a comment - 27/Mar/14 5:48 PM 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)

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.

Dan Poltawski
added a comment - 27/Mar/14 6:08 PM 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.

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...

Juan Leyva
added a comment - 27/Mar/14 6:25 PM - 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

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).

Dan Poltawski
added a comment - 27/Mar/14 6:30 PM 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?

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

Juan Leyva
added a comment - 27/Mar/14 8:37 PM 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

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..

Dan Poltawski
added a comment - 28/Mar/14 10:11 AM 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..

Asaf Ohayon
added a comment - 02/Apr/14 8:22 PM 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

Asaf Ohayon
added a comment - 02/Apr/14 9:47 PM 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

I have setup the Shibboleth SP on a couple of servers now. I had to find the HTTP header variable which had the authenticated username in then put that in to the webapp (Heritage and Moodle so far)'s setup form. e.g. on some SPs REMOTE_USER sends the username. But we would need to get the IdP login box up to trigger it then trap the fact the browser is trying to redirect back to moodle - then look for that header (not stored in $_SESSION IIRC).
Just a thought.

Dave Perry
added a comment - 24/Apr/14 8:56 PM I have setup the Shibboleth SP on a couple of servers now. I had to find the HTTP header variable which had the authenticated username in then put that in to the webapp (Heritage and Moodle so far)'s setup form. e.g. on some SPs REMOTE_USER sends the username. But we would need to get the IdP login box up to trigger it then trap the fact the browser is trying to redirect back to moodle - then look for that header (not stored in $_SESSION IIRC).
Just a thought.

We are going to implement the auth process as a new auth plugin, the app will detect if the auth plugin is enabled and then if the user that is trying to log-in uses a SSO auth method (Shibboleth or CAS) a new browser pointing the Moodle installation will be opened, once the user is logged in Moodle, the browser will be closed and the app launched.

This is going to be a contributed plugin (add-one), it may be included in core for 2.8

Juan Leyva
added a comment - 05/May/14 6:34 PM Hi again,
an update on this issue:
We are going to implement the auth process as a new auth plugin, the app will detect if the auth plugin is enabled and then if the user that is trying to log-in uses a SSO auth method (Shibboleth or CAS) a new browser pointing the Moodle installation will be opened, once the user is logged in Moodle, the browser will be closed and the app launched.
This is going to be a contributed plugin (add-one), it may be included in core for 2.8
Regards

Hi Juan - we use a SAML plugin as our SSO auth method, connecting to an ADFS IdP. The plugin is maintained by a NZ-based Moodle partner. Will your proposed implementation support this method or is it going to be specifically restricted to CAS/Shibboleth?

David Sturrock
added a comment - 05/May/14 6:51 PM Hi Juan - we use a SAML plugin as our SSO auth method, connecting to an ADFS IdP. The plugin is maintained by a NZ-based Moodle partner. Will your proposed implementation support this method or is it going to be specifically restricted to CAS/Shibboleth?

Juan Leyva
added a comment - 05/May/14 6:56 PM Hi David,
you will be able to configure in the plugin settings which plugins are considered SSO plugins (default to Shibboleth and CAS but you can add there your custom one)
Regards

David Sturrock
added a comment - 05/May/14 7:04 PM Excellent news Juan, I appreciate the flexibility you are building into this solution. Looking forward to being able to use the app on the 2 sites we maintain

Great news Juan, we are possibly going to be using Shibboleth for Office 365 when it comes in the summer, and want to put moodle behind it too - the app supporting it issue caused hesitance at this end.
What is the earliest moodle version the contrib plugin will work with? We're on 2.5.

Dave Perry
added a comment - 06/May/14 4:27 PM Great news Juan, we are possibly going to be using Shibboleth for Office 365 when it comes in the summer, and want to put moodle behind it too - the app supporting it issue caused hesitance at this end.
What is the earliest moodle version the contrib plugin will work with? We're on 2.5.

Juan Leyva
added a comment - 15/May/14 3:51 PM Hi David,
the plugin should work with any Moodle 2.2 and above version (well, the app requires Moodle 2.4 so I will test only in 2.4, 2.5 and 2.6)
As far as I know, there are not major changes in auth plugins https://github.com/moodle/moodle/blob/master/auth/upgrade.txt

I've created two tasks for this issue, once for developing the Moodle plugin and the other one for the changes needed in the app.

The Moodle plugin is almost done, I'm starting to work in the app changes.

The general workflow will be:

When a user open the app (first time) a URL pointing to a Moodle site is required

The user enters the URL and click "Check"

The URL is checked. At this time, the auth/moodlemobile/check.php script is called: If the plugin is installed in the Moodle site, the app retrieve the type of login that should be performed

If the type of log in is "using the app", just under the URL fields two new fields (username and password) are displayed

If the type of log in is "using the browser", a message indicating that the user must enter his credentials at the Moodle site using the device browser is displayed. The message is closed and the browser is open, the user enter his credentials in the Moodle site and once logged the app is launched again with the user authenticated.

There is another type of log in, that is first try to log in using the credentials entered in the app and if it fails open the browser for log-in

If the plugin is not installed in the site, the type of login choosen is allways "log in using the app"

Juan Leyva
added a comment - 16/May/14 10:15 PM I've created two tasks for this issue, once for developing the Moodle plugin and the other one for the changes needed in the app.
The Moodle plugin is almost done, I'm starting to work in the app changes.
The general workflow will be:
When a user open the app (first time) a URL pointing to a Moodle site is required
The user enters the URL and click "Check"
The URL is checked. At this time, the auth/moodlemobile/check.php script is called: If the plugin is installed in the Moodle site, the app retrieve the type of login that should be performed
If the type of log in is "using the app", just under the URL fields two new fields (username and password) are displayed
If the type of log in is "using the browser", a message indicating that the user must enter his credentials at the Moodle site using the device browser is displayed. The message is closed and the browser is open, the user enter his credentials in the Moodle site and once logged the app is launched again with the user authenticated.
There is another type of log in, that is first try to log in using the credentials entered in the app and if it fails open the browser for log-in
If the plugin is not installed in the site, the type of login choosen is allways "log in using the app"

Juan Leyva
added a comment - 22/May/14 6:42 PM - edited This video shows how it's the process in Android, it should be similar in the iOs versions (I have to test it in iOs) but it currently works for Android
https://www.youtube.com/watch?v=cl8rsyyyg9g
And this is how a normal login works:
Notice that we first check if the URL is valid (webservices enabled, SSO forced, etc..) in this case, a normal login in the app is done
https://www.youtube.com/watch?v=X7xp9pYbQ4I

Hi Juan,
It might be an add-on to your actual development, but it's quite annoying to type moodle's url each time you want to access it. Wouldn't it be possible to have a checkbox to keep connection alive, or at least have a way to call back a previous connection url ?
Nicolas

Nicolas Truchaud
added a comment - 22/May/14 7:15 PM Hi Juan,
It might be an add-on to your actual development, but it's quite annoying to type moodle's url each time you want to access it. Wouldn't it be possible to have a checkbox to keep connection alive, or at least have a way to call back a previous connection url ?
Nicolas

Notice also that if the user has logged into Moodle in the system browser, the app will launch the browser but since the user is logged it will launch the app immediately (without asking again the user to enter his credentials)

Juan Leyva
added a comment - 22/May/14 7:18 PM Notice also that if the user has logged into Moodle in the system browser, the app will launch the browser but since the user is logged it will launch the app immediately (without asking again the user to enter his credentials)

Juan Leyva
added a comment - 22/May/14 7:26 PM Hi Nicolas,
once logged in the app, you don't have to type your url/credentials again.
You will be logged until the "auth token" is reset in the Moodle site or you do "a logout" in the app using the menu option.
Regards

Juan Leyva
added a comment - 04/Jun/14 4:32 AM Request for volunteers:
If anyone want to test this in a site using Shibbolet or CAS please email me at juan AT moodle.com
In order to test, you need to have an Android device and you should be able to install the new add-one in your test site
Or you can just install the add-one and I can do the testing

Juan Leyva
added a comment - 05/Jun/14 4:19 PM Hi,
thanks to all the volunteers that have tested the app with CAS, I need some volunteers for testing the app with Moodle sites using Shibboleth
Here you have instructions for testing:
https://docs.google.com/document/d/1qgM4fTC9XS_bl3RHY-KHwT5iOsoemHAZ1LxJuCGNtnc/edit
You can contact me at: juan AT moodle.com
Regards

Dan Poltawski
added a comment - 05/Jul/14 12:22 AM Hi Juan,
I was just playing with this on a site you know about and this method does not work for system admins (moodle prevents them from creating a token). I suppose you know this?

Juan Leyva
added a comment - 05/Jul/14 12:28 AM - edited Yes, it's documented here: http://docs.moodle.org/27/en/Moodle_Mobile_additional_features#Security
And the reason is: http://docs.moodle.org/dev/External_services_security#Random_all-time_valid_token
An administrator has the ability to create a token for another Moodle user but not for himself neither for another administrator (for security purpose).
It's curious but that rule was relaxed for the official Mobile service.

Our Moodle uses the Shibboleth authentication method. This seems to just basically work. The only issue I've noticed is on iOS, when a particular resource or content type is not available in the moodle mobile app, a redirect to the browser occurs.

Normally this would not be an issue, since we have a 4 hour session timeout on our idp, so folks should just get to the resource once logging in. iOS however, decides after some non-deterministic amount of time to kill the safari browser. Once that happens, you loose your session cookies to the idp, so trying to access a resource from within the app, which redirects to the browser, will result in an authentication prompt.

This is an artifact of the way that iOS works, which has caused some support issues for us in the past. Android does not seem to suffer from this issue.

Jason Howe
added a comment - 06/Aug/14 2:31 AM Our Moodle uses the Shibboleth authentication method. This seems to just basically work. The only issue I've noticed is on iOS, when a particular resource or content type is not available in the moodle mobile app, a redirect to the browser occurs.
Normally this would not be an issue, since we have a 4 hour session timeout on our idp, so folks should just get to the resource once logging in. iOS however, decides after some non-deterministic amount of time to kill the safari browser. Once that happens, you loose your session cookies to the idp, so trying to access a resource from within the app, which redirects to the browser, will result in an authentication prompt.
This is an artifact of the way that iOS works, which has caused some support issues for us in the past. Android does not seem to suffer from this issue.