I would like to draw your attention to some important changes in plumbing that is used in the hybrid integration between Sakai 2 and Sakai 3. First a little background… Previously, an authentication mechanism existed that allowed a system external to Sakai 2 to call into its services while not prompting the user for authentication and trusting the external system for the user’s identity. This has been used primarily to allow services in Sakai 3 to call services in Sakai 2 to retrieve, for example, lists of sites for which the user is a member. This kind of authentication should not be confused with a single-sign-on solution like CAS which casts the end user as the primary actor. This type of authentication mechanism is used for server-to-server communication, on behalf of the user, and is established by system administrators who declare trust relationships between the two systems. The basic flow looked like:
- End user requests data from Sakai 3 via HTTP GET method (e.g. to get a set of Sakai 2 sites for the current user).
- Request is proxied through Sakai 3.
- Sakai 3 adds a header to the request: X-SAKAI-TOKEN (includes username).
- Sakai 2 receives the request and examines the X-SAKAI-TOKEN.
- If the token is valid, establish a new session based on the username passed in the token, and process the request.
So let’s examine this a little closer… An example X-SAKAI-TOKEN looks like:
The token is comprised of three pieces of information separated by semicolons:
- EEFSxb/coHvGM+69RhmfAlXJ9J0= : A cryptographically secure hash of the message.
- admin : the username of the current user signed into the calling system, i.e. Sakai 3 in this example.
- 1273688664630 : Number of milliseconds since the epoch.
Inquiring minds are probably wondering why Sakai 2 would trust such a token… I mean, just because a web request shows up at your front door and has some official looking identification, does not mean we should allow them to run code as admin, right? Well that is where the next concept is introduced: the shared secret. Think of a shared secret as a password that both systems know. Sakai 3 used the shared secret to sign the message and since Sakai 2 also has the shared secret, it can verify the integrity of the message (i.e. ensuring the message has not been spoofed or tampered with in any way). Just to be clear, the message admin;1273688664630 is signed using the shared secret to create the hash EEFSxb/coHvGM+69RhmfAlXJ9J0= and then the hash is prepended to the message to create the token X-SAKAI-TOKEN: EEFSxb/coHvGM+69RhmfAlXJ9J0=;admin;1273688664630. Now Sakai 2 has everything it needs to verify the token. It can use it’s own shared secret to compute a hash of the message and verify it equals the hash that was passed in the token. If the hashes are equal, the message is valid and has not been tampered with in any way.
This capability is great for calling into Sakai 2. But lately I have started looking into how tools or widgets might start passing results between systems. Think about a student submitting an assignment to a Sakai 2 tool and having the results posted to a Gradebook running in Sakai 3. We needed a way for Sakai 2 to be able to call into Sakai 3 using the X-SAKAI-TOKEN mechanism — and now we have it! Thanks to some help from Dr. Ian Boston, we have pulled the same authentication and identification techniques into Sakai 3; with some improvements of course:
- The HTTP header X-SAKAI-TOKEN has been renamed x-sakai-token (to save on your CAPS LOCK key).
- The signature has been upgraded to the latest and greatest standards: RFC 2104 compliant HMAC (Hash-based Message Authentication Code). Thanks to Carl Hall for adding this capability to Sakai 3.
- sakai.auth.trusted.server.enabled: setting to completely enable or disable this feature.
- sakai.auth.trusted.server.safe-hosts: setting to control which other servers we trust.
- The Sakai 2 implementation has also been updated with the same great improvements.
So now that we have some plumbing installed, I will return to considering results passing between Sakai 2 and Sakai 3. :)
PS – This same mechanism could be used with 3rd party systems if desired. Build a message, sign it with an HMAC, and stuff it into an HTTP x-sakai-token header and away you go… Think about it…