External: Student clicks on URL to go to their online Moodle Course.
External: URL is written to include our authentication model and include the students ID.
Internal: We recieve the URL, check the auth hash and get a match so its a legit login attempt.
Internal: Using the students ID we find their internal moodle id and select the students username and password(hashed).
Internal: Pass the selected username/password into the login form for Moodle.
Internal: Moodle creates the session/cookie to show the student as logged in.
Internal: Student is taken to their course homepage.
The only problem I'm having is the password in the database is hashed and the login form takes the posted password and hashes it again, so this obviously will result in a failed login attempt. Is there anyway I can bypass the first part and just have moodle continue onward from AFTER where it hashes the posted password? So it creates the session and logs the student in.
I've been looking at the code and I'm not finding an easy way to do it. This needs to invole no modification of the Moodle code itself so our stuff can be used with anyones Moodle.
Its not pretty but it may help!
Of course users will not be able to access moodle except through your system after this as they wouldn't know the password.
It depends upon how is your external link works, what are the parameters it is posting. Along with userid, you can pass one more parameter.
By validating the additional parameter, we can by pass password encryption.
Other solution:
check your server(php) setup for Curl functions.
print "<form action='../login/index.php' method='post' name='login' id='login'>
<input type='text' name='username' size='15' value='admin'>
<input type='password' name='password' size='15' value='*********'>
<input type='submit' name='Submit' value='Submit'>
</form>";
print "<script> document.login.submit() </script>";
This is trying to spoof the actual human input. If we could get this to work it'd be fine. I found a way already to allow users to login via their plain-text passwords in Moodle or their passwords HASH. So I can easily just select the HASH from the database and post it through to the Moodle login page. The problem is the above solution isn't working. It posts fine but Moodle doesn't finish the login sequence. I tried using Shibboleth but that ended up being a larger headache then it was worth. Any other ideas?
I'm working on a similar problem. We are using a student portal as well. My initial solution was to create a form with hidden fields where the users username and md5 password were stored. Then I modified authenticate_user * function in moodlelib.php. Modified auth/manual/lib so the script would accept md5 encrypted passwords. That worked well. But I'm not thrilled about md5 passwords sitting out there in a hidden field.
So. I'm trying something new. I'm thinking about customizing the login. A hidden field which contains a unique session id is submitted to the new login page. The page checks a remote session table, verifies that they authenticated in the last 10 minutes or so grabs the user id, username and password form it and then sends it to moodle for the login. What do you think?
My solution was copying two moodle functions into another
file, copying the two login pages making a few tweaks to them and creating a
custom auth module.
The two Moodle Functions:
(Original Name) -> (New name to avoid conflicts)
require_login -> require_login_api
authenticate_user_login -> authenticate_user_login_api
The first function 'require_login' I only took the first 45 lines of code.
Somewhere in there there is a session being started or altered that I just
can't find. So rather fight it I just call the copied function and made it so
it redirects to my custom login page.
The second function 'authenticate_user_login' appears to be where the login
process begins. I copied it and placed a small hack in it so it would use our
authentication module instead of the default that Moodle is currently set to.
} else {
$auth = $user->auth;
$auth = 'apiauth';
}
This is right at the end of all the checks, I just swap the variable holding
the authtype from what Moodle says to what I say.
Next up we have the custome auth module. It's simple, I just took the email one
and made it look like this:
function auth_user_login ($username, $password) {
if ($user = get_record('user', 'username', $username)) {
return ($user->password ==
$password);
}
return false;
}
Now it doesn't do a MD5 hash of the incoming password. Using this custom auth
module will mean that students can still login to the front page with ONLY
their password and not the hash of their password. If you were to go to the
secondary custom login page you would only be able to get in with a hash and
not a password.
The login pages were modified to simply call each other and I changed it so
they call our custom authentication function 'authenticate_user_login_api'. Oh,
I also added it so the username/password are passed into them via the URL (Yeh,
I know not very secure). Then it simply puts them into the username/password
box in the HTML and there is a line of JavaScript to automatically submit the
form. The only thing left is to make it remember where the student was
originally going and forward them there instead of the students homepage.
Now the concern about security and allowing MD5 hashes to be used as login
passwords. I think I have found a way to solve this problem as well. If someone
were to find a students MD5 hash it means they are sniffing the network or in
your Moodle Database. If its the latter you have bigger problems then letting
people login with hashes. If its the former they could sniff the students clear
text password anyway so it doesn't matter. I'm going to add an extra security
measure where you can't actually get into the custom login page unless you've
already gone through the first half of our API. Once thats complete it should be
pretty secure.
I hope that's clear as mud, let me know if I need to elaborate a bit more.
Instead of a Username/Password, I would like to give moodle a SessionID string and then have it use a SOAP service to lookup the User/Information that is associated with that Session (on a server running Sakai).
So far I've written a "moodle/auth/sakai" plugin that authenticates the username/password against my server using SOAP.
Any pointers on what code I need to hack/extend to pass in a single string that would automatically cause an authenication hookup would be appreciated.
Thanks,
Steve
I got my system to work. It's running great.
Of course this requires username and passwords to be stored in two separate places and updated in a single place. But that's no biggie either.
I have the SOAP stuff working, thats not a problem.
I need to figure out what to hack in order for the log-in to take a single parameter (instead of two username/password). This single session key will then get checked against another server to get the credentials.
I guess maybe I could just use either the username and/or password field and ignore whatever is in the other one.