Tuesday 23 February 2016

Leveraging the SIMS Active Directory Provisioning Service to support Single-Sign-On

Like a great many UK schools, we use Capitas SIMS as our school MIS. It's where the vast majority of our data, of all kinds, lives and is generally considered to be the 'source of truth' for all kinds of data about our students and staff.

Our computer network, again like most of the rest of the world, is based on Microsoft Active Directory. For our IT needs, this is another 'source of truth'. It provides the authentication database for all kinds of services - from standard desktop logons, to web proxy authentication, to 802.1x authentication to wireless networks, to managed print accounting, to e-mail, to Moodle and more. Active Directory security groups determine all kinds of policies and memberships across our environment and we try hard to tie as much as we can into this central infrastructure - as with well over 1000 active accounts, trying to do so manually would be an impossible task to stay on top of.

The problem, historically, has been maintaining a relationship between SIMS and Active Directory. SIMS already knows who is on-roll and employed at our school, it knows what classes those people are in, it knows who has responsibility for what, it knows a lot of stuff! SIMS is also the 'source of truth' that a number of popular 'hosted', 'cloud' or 'SAAS' (depending on your love of buzzwords) applications use to automatically discover that same information and populate their own databases. Third party extraction services exist, such as GroupCall, that the providers of external services can use to discover names of students on roll, names of staff, classes and who is in them, contact details for parents, behaviour and achievement information and more in order to make their products work, without having to ask school staff to manually import thousands of pieces of information somehow.

What these hosted application can't do however, is create any kind of a link to Active Directory - SIMS just doesn't have the information available to it. The result is that schools end up trying to manually maintain separate sets of usernames and passwords for a myriad of applications. This is difficult for schools - larger secondaries will see students starting and leaving most weeks. It's also difficult for users - trying to remember 10+ different username formats and maintain passwords to go with them is difficult - and doubly so if you joined a school mid-year and missed the bit where everyone else was given the relevant information. The answer is obviously single-sign on and support from externally hosted applications for schools to plug into authentication providers such as Active Directory. However, the challenge is still how to create and maintain that 'link' between SIMS and Active Directory, so a computer can know 'The person with Active Directory username bob is actually Bob Smith, in 7GD, we should show Bob Smiths homework when someone with his username logs into our website rather than Bob Jones'. You also want that 'link' to exist automatically and "just work" as people come and go or you're just moving your administrative overhead around rather than reducing it.

The most sensible answer i've found so far is the aptly named 'Active Directory Provisioning Service'. Capita make this add-on product for SIMS - and it's designed to, as the name suggests, provision accounts in Active Directory straight out of SIMS for students, staff and 'contacts' (parents usually). This product appears to be primarily designed to provide accounts for other products that Capita provide such as the SIMS Learning Gateway (in fact, that's why we have it in the first place), but it does just happen to open up a load of other integration options with a bit of work.

On its own, the ADPS can be handy, but doesn't change the world. It creates user objects, and it will even put those user objects into some handy security groups (including by class), but that's about it. In order to make these user objects useful for people to actually use for more than just simple web services, most schools will need to 'do stuff' with them (such as move them to suitable OUs, add them to existing security groups, create mailboxes behind them, create home shares, set profile paths - that kind of thing). We've created some handy scripts that automate most of this for us now, perhaps more on that another time - but the point is, most people probably won't have got much more out of the ADPS than provisioning accounts for SLG and then consolidating those accounts with an existing user you'd already made with some other method. However, the clever stuff starts to become more apparent when you take a look at how ADPS actually works.

The ADPS application makes, at install time, a few schema changes to Active Directory. The one i'm most interested in, is the one called 'capitachildrensservicesClientEntityGuids'. When we take a look at this field for a user object that has either been created by, or consolidated from the ADPS we can see some values appear:


This particular field, when populated, contains 2 unique IDs, seperated by a pipe character. I'm not sure what they are derived from exactly, but the important thing is:
1: They are unique per person
2: You can report on one of them using the SIMS reporting engine

The fact that you can report on the 'capitachildrensservicesClientEntityGuids' value means that now, there's a known, fixed, link between Active Directory and SIMS, that ADPS will maintain for you, that you can ask SIMS to produce reports containing data of your choice that includes it.

The specific service I was looking to provision SSO for while researching thing was something our school use called ShowMyHomework. As the name suggests, it's a website that shows you your homework. Initially, these guys couldn't seem to understand why SSO might be a thing that schools would want, but in recent years it seems they've finally seen the light and now provide support for talking LDAPS to their schools to authenticate users, rather than relying solely on their own disparate authentication database - and it seems to work well! SMHW pull data on students and classes from SIMS using GroupCall - and the unique identifier from SIMS that they have chosen to use to identify users within their platform is the SIMS 'ID' field. This seems to be a fairly common unique identifier for 3rd party products to use, so that's the one I wanted to automatically populate Active Directory with in this case - but it would be trivial to extend that to basically any value that the SIMS reporting engine will spit out.

So, now that we've discovered the link that ADPS creates, lets use that to populate our Active Directory with the SIMS 'ID' value for everyone.

1: Design a SIMS report that includes both the SIMS Person_ID and the 'External ID' for all our students on roll. You could do a similar one for staff or contacts, but this example focuses on students. The report should output to XML.
Tips: Find the 'External ID' data type under the 'CESThirdPartyFields' category. The SIMS user that runs the report will also need to be a member of the 'Third Party Reporting' usergroup to be able to report on the Person_ID object - SIMS will just report null values otherwise.


2: Either create a custom Active Directory field for your users by making a small edit to the Schema (mine was called hwcsSimsId) or designate an existing field to re-purpose.

3: Create a script of some kind to loop through all your Active Directory users, look for ones that have a 'capitachildrensservicesClientEntityGuids' value set, but not your custom SIMS ID set, parse the XML that SIMS will provide you to match the two values up and set the SIMS ID on missing users.

My attempt at this, written in PowerShell is here (MISID-Import-Students.ps1)

This script, that requires PowerShell 3 and the Microsoft Active Directory command line utils available, will:

  • Read in the SIMS XML Report
  • Discover all the user accounts in your Active Directory, starting at the base path of $SearchLDAPBase
  • For each account, look for the ones that have a  'capitachildrensservicesClientEntityGuids' value, but not a value under the $ADAttribute field
  • For those accounts, take the  'capitachildrensservicesClientEntityGuids' string, split it apart at the '|' symbol and store the second value (this is the 'External ID value')
  • Try and find a match in the SIMS XML data
  • If it finds one, take the value for 'ID' and write it to the $ADAttribute Active Directory field
The end result is, all being well, values appearing in your $ADAttribute field:

4: When this all works, create a Scheduled Task that uses the SIMS CommandReporter to run your SIMS report and produce new XML, then parse it and update your Active Directory as appropriate, all automatically. This runs once a day, overnight, for me - but the schedule could be anything. An example of how this whole process might work is in the same GitHub repo (MISID-ExportFromSIMS.ps1) along with some example XML output (SIMS ID To External ID.xml).

The end result is that as new users arrive with us:
  • GroupCall does its thing, sends updates to SMHW (or the service of your choice) who provision things their end, automatically
  • We run a SIMS report and update Active Directory with the SIMS ID of our new starter overnight, automatically
  • The user attempts to log into SMHW using their normal school username and normal school password. SMHW make an LDAPS query to us over the internet, authenticate the user and request their SIMS ID from our Active Directory
  • The user sees their environment on the SMHW platform - with 0 human involvement required (beyond ensuring they exist in SIMS - which is work we need to do anyway).
The same also becomes true for leavers - their accounts are de-provisioned, again, without anyone having to manually process them.

This seems to work well - and could obviously be extended to cover a number of similar applications where a tighter integration with authentication services is advantageous.



2 comments: