How does the function authenticate_user_login handles non-core authentication plug-ins?

How does the function authenticate_user_login handles non-core authentication plug-ins?

by Visvanath Ratnaweera -
Number of replies: 6
Picture of Particularly helpful Moodlers Picture of Translators

Hi all

I need to understand how the function authenticate_user_login handles non-core authentication plug-ins, in particular Shibboleth.

In Moodle 3.5 code auth/shibboleth/index.php around line 54 there is this test,

if ($shibbolethauth->user_login($frm->username, $frm->password) 
&& $user = authenticate_user_login($frm->username, $frm->password, false, $reason, false))
{
   complete_user_login($user);

which fails because the second condition $user = authenticate_user_login($frm->username, $frm->password, false, $reason, false) returns false.

Tracing authenticate_user_login in lib/moodlelib.php I see that the execution does not enter any of the code blocks and therefore exits with False. The content of the $auth array explains that. It goes through the authentication mechanisms of core Moodle, but not Shibboleth which is a plug-in (and activated).

Could somebody explain to me how authenticate_user_login is expected to return True, when the function does not iterate through an auth = 'shib' block.

Average of ratings: -
In reply to Visvanath Ratnaweera

Re: How does the function authenticate_user_login handles non-core authentication plug-ins?

by Visvanath Ratnaweera -
Picture of Particularly helpful Moodlers Picture of Translators
In the mean time found the history of Shibboleth Authentication - from A.D. 2005. I understand it as Shibboleth verify the account on its own HTML form and returns username back to Moodle. Moodle makes a "pseudo-trip" to authenticate_user_login so that the full user details may be collected.

Interestingly I am getting exactly the same error message although Shibboleth account is positively verified. "You seem to be Shibboleth authenticated but Moodle has no valid account for your username. Your account may not exist or it may have been suspended." (screen-shot)


I am not sure whether this is a topic for the Authentication forum.
Attachment shib-error1.png
In reply to Visvanath Ratnaweera

Re: How does the function authenticate_user_login handles non-core authentication plug-ins?

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Looking through the code of authenticate_user_login(): https://github.com/moodle/moodle/blob/master/lib/moodlelib.php#L4411

There are a number of steps - first it tries to find an existing user account with the username provided - if it succeeds at this point, then it gets the 'auth' method from that user, in order to check with that specific authentication method to see if the user can log in.

If there is no user account found, then it checks against all enabled authentication methods (in the configured order), until it finds a user that matches.

So, the most obvious reason why authenticate_user_login() might not call shobboleth is that the user account exists (with the given username), but that user is configured with a different authentication method (e.g. a 'manual' user account, or an 'email-based self-registration' account). You could also check the user is not suspended.

In reply to Davo Smith

Re: How does the function authenticate_user_login handles non-core authentication plug-ins?

by Visvanath Ratnaweera -
Picture of Particularly helpful Moodlers Picture of Translators
Hi Davo

Thanks for explaining the logic. It makes sense. This Moodle instance has users coming from two authentication methods: Shibboleth and manual. From the https://moodle.org/auth/shibboleth/README.txt (item 6) it seems that some modifications are necessary to get both going at the same time. I notice that  this site does it differently.

This is how:
- login/index.php has been modified:
if (isloggedin() and !isguestuser()) {
echo $OUTPUT->box_start();
$logout = new single_button(new moodle_url($CFG->httpswwwroot.'/login/logout.php', array('sesskey'=>sesskey(),'loginpage'=>1)), get_string('logout'), 'post');
$continue = new single_button(new moodle_url($CFG->httpswwwroot.'/login/index.php', array('cancel'=>1)), get_string('cancel'), 'get');
echo $OUTPUT->confirm(get_string('alreadyloggedin', 'error', fullname($USER)), $logout, $continue);
echo $OUTPUT->box_end();
} else {
include("index_form.html"); // <- this line has been added
if ($errormsg) {


- The index_form.html is attached

So the login page brings two HTML forms. The one for the manual logins work as expected but not the Shibboleth logins. If the user is correctly authenticated in Shibboleth form but does not exist in Moodle it throws the "You seem to be Shibboleth authenticated but Moodle has no valid account for your username. Your account may not exist or it may have been suspended." error rather than creating the user.

The original site was Moodle 3.1 and still works perfectly. The site I am testing is it migrated and upgraded to Moodle 3.5 (3.5.13). I am strongly inclined to continue the method used in the old site, opposed to the method in README.txt.

I wonder whether the login token which has been added somewhere in 3.5 spoils the process. How could I check?


In reply to Visvanath Ratnaweera

Re: How does the function authenticate_user_login handles non-core authentication plug-ins?

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
If it was the login token that was causing the problem, then you'd get a very clear error message about it. As it is, the form you attached has a token in it anyway, so it shouldn't be a problem.

I'm afraid I can't really offer any further insight at this point - my next step, if I had a copy of the site's code set up locally, that was able to reproduce the issue, would be to enable xdebug + stick a break point in the code in my IDE and step through it a line at a time, until I found out exactly where it was doing something unexpected.
In reply to Davo Smith

Re: How does the function authenticate_user_login handles non-core authentication plug-ins? [SOLVED]

by Visvanath Ratnaweera -
Picture of Particularly helpful Moodlers Picture of Translators
Hi Davo

Excluding the login token was a big help. The next suspicion was the differences in the Apache vhost file. What happened was that our local identity provider is too generic (not Moodle-specific) and too far upto date (mine is an old installation) that I got conflicting instructions. Started the whole thing anew and followed up the original line as I explained partly in my previous post. It just worked!

Problem SOLVED. Thanks for all the support!