Moodle & Azure Active Directory, the trials and tribulations
Recently I’ve undertaken the task of moving our teaching and learning system to authenticate using Azure AD.. There’s some 120,000 accounts on our Virtual Learning Environment, whether these are active / inactive or suspended doesn’t matter they all need to be able to be logged into if required by the user.
So how did I go about it?
By first installing the following plugins from the Office 365 set:
- Microsoft Office 365 Integration (local_o365)
- OpenID Connect (auth_oidc)
- Office 365 Repository (repository_office365)
- Microsoft Block (block_microsoft)
I used these plugins rather than the core OAuth2 method as they promise much higher level of AD customisation and are developed by Microsoft, as well as the extra levels of integration to Office 365.
The main task I was trying to complete was to attempt to use the account pattern match function, so the existing LDAP accounts could be matched to the ones within our Azure AD and gain a complete single sign on solution for our VLE… All this sounded like a simple task to achieve.
The one thing you must do, is read the instruction manual for this plugin set, this is some 20 pages in length, find a quiet place before attempting this, there’s a lot to take in and a lot of prerequisites that you need to have in place, obviously one of these is a working Azure Active Directory, running in Azure portal.
I won’t go into detail of the installation or setup as the 20 pages does a good job of explaining that. What I do need to explain is the parts of what to do when your trying to achieve something when the manual has stopped.
Such as the one part that lead me down this path, the ability to match any preexisting moodle users with the same named accounts in Azure AD
The manual says “This requires the “Match” setting above to be enabled. When a user is matched, enabling this setting will switch their authentication method to OpenID Connect. They will then log in to Moodle with their Office 365 credentials. Note: Please ensure the OpenID Connect authentication plugin is enabled if you want to use this setting.” and that is it..
Well I can tell you I spent far too much time attempting to get this working to no avail. I’ve since learnt that our hosting partner has also tried it to no avail. So just don’t bother, unless it gets fixed in a later release than 3.5.0.2, see my github issue ticket that I’ve raised to see if it get solved in a future release or an explanation by the developers.
Here is an example of the errors which were being kicked out by the Azure AD sync in scheduled tasks:
......... Syncing user <strong>studentID@tenant.ac.uk</strong> ......... Assigning Moodle user 30 (objectid 3c1a8a67-1234-4ace-bc38-22b0e4aa973e) to application ......... Could not assign user "<strong>studentID@tenant.ac.uk</strong>" Reason: No token available for usersync ......... Found a user in Azure AD that seems to match a user in Moodle ......... moodle username: <strong>studentID</strong>, aad upn:<strong>studentID@tenant.ac.uk</strong> ......... User is already matched. ......... User is now synced.But nothing gets written back to the database, so whatever ‘No token available for usersync‘ means, is the reason why.
Additional to the original post
Here’s the answer to the above, see my github ticket for full details
Looking at the output you posted, it looks like this user is a “matched” user – i.e. they have not yet logged in to the site, correct? A “matched” user just sets up a user for a future connection, but the user has to actually log in to the Moodle site using their Office 365 credentials to complete the connection. User information syncing will only happen after this connection has been completed.
I’ve not proved this to be the case, as the plugins are only on our Dev server, until the summer upgrade, but I will be trying it again then.
Back to original post
After much soul searching the answer became obvious, just write the required field to the mdl_user table, using SQL on the back-end MySQL database.
Here is the SQL which I used to do that:
The SQL is updating the username and adding our Azure student and staff tenant to that. The regular expression, which you might not require is only checking for a ‘username’ which is 8 digits in length.
#SQL to change all students
UPDATE mdl_user SET username = concat(ifnull(username,""), '@xxx.xxxx.ac.uk'), auth = 'oidc' WHERE auth = 'ldap' AND username regexp '^[0-9]{8}\@xxx\.xxxx\.ac\.uk$' AND email like '%@xxx.xxxx.ac.uk';#SQL to change all staff
UPDATE mdl_user SET username = concat(ifnull(username,""), '@xx.xxxx.ac.uk'), auth = 'oidc' WHERE auth = 'ldap' AND username regexp '^[0-9]{8}\@xx\.xxxx\.ac\.uk$' AND email like '%@xxxx.ac.uk';I hope the above helps you get to where I am quicker and with less pain.
I’ll finish here for now and go into detail about how to plugins handles new accounts at another time.
Addition to original post : Sync’ing new users
This works like a dream, I increased the cron task ‘Sync users with Azure AD’ to run every 7 mins, so it could chew through our AAD (Azure Active Directory) and it just creates users for you..
User Creation Restriction
Beware when using this, the obvious choice of the UPN / Username is not here, Object ID is not that, I had thought it was and wasted a day of tinkering and wondering why my Reg Ex was not working
(?im)^[0-9]{8}\@staff\.xxx\.ac\.uk$|(?im)^[0-9]{8}\@student\.xxx\.ac\.uk$It because it wasn’t trying to match to the username, the Object ID looks like this:
06273d5ea-2ef1-1d10-a315-4ac234fe34f2I’ve asked the developer to add this as a feature enhancement, see here
We’ve now used the option at the bottom, ‘Office 365 Group Membership‘ and created a dynamic security group, this is working as expected, which is fabulous, some people on the GitHub forum are asking for the ability to use more than one group to do this.
We’ve also used RegEx to block logins that are not formatted like our ID 12345678@staff.xxx.ac.uk or 12345678@student.xxx.ac.uk
Using the same regex as above, for these settings see User Restrictions in /admin/settings.php?section=authsettingoidc on your site.
Go Live for Academic period 1920
Lessons learned
September 2019 and all seems to be working well. things I have noted since going live:
- All accounts need to be set as active, moving from LDAP to OpenID Connect may have left some in a suspended / inactive state, this flag does not get set via what is set on Azure. So making all accounts active is the best thing to do. If a user attempted to authenticate and their Moodle account was inactive then they saw ‘ERROR1’ or equally useless error when using Office365 suite 3.6.0.1
- Because the ‘Block sign in’ flag from Azure doesn’t pass across there is no way of knowing which accounts can be ‘safely’ deleted. I’m trying to get this added as a feature enhancement.
We had a similar experience with the latest plugin version on M3.6. Hours of frustration. At the time of writing the user match function doesn’t work as expected. I had to do likewise. We had a much smaller number of users, so we updated user accounts to include the tenant via csv user upload. Still some random authentication issues though. Useful post, hope it helps others.
My question to the developer made it sound like that the sync match doesn’t complete the matched user first logs in. Did you try that?
Hi Raymond – can you we talk to you about this – we would like to do something similar and need to learn quickly – it sounds like you have and understanding and have been through this already. It would be great to have a chat. I work as deputy IT director at a London University. Many thanks in advance.
Sure Nigel get hold of me at r.g.reid@mmu.ac.uk