Pratt users accessing the CMS needed to be able to do so without noticing the actual login process.
This single sign-on system was to be used by all of Pratt Institute, faculty, students and staff alike.
We built a custom module for Pratt's website which connected to their ADFS identity system.
Pratt Institute's faculty, staff and student body number in the tens of thousands.
Solspace lead the development on the ADFS integration with Pratt's site CMS, ExpressionEngine.
We leveraged Microsoft Azure to create a reliable dev environment which allowed us to isolate variables and problems.
Microsoft and the LAMP stack are very different worlds. Getting them to work together without friction can be a challenge. Our client, Pratt Institute, needed to allow users who were logged into their ADFS (Active Directory Federation Services) server to easily move between it and their ExpressionEngine CMS driven website. There is an open source protocol available, supported natively in Microsoft ADFS, that allows this to happen. It’s SAML 2.0. There’s also a widely used PHP library for SAML 2.0, SimpleSAMLphp. So there was some glue available on both sides. We just needed to get the glue to stick two very different surfaces together.
Pratt users who would be accessing the CMS needed to be able to access it without noticing the actual login. The CMS was to inherit the valid logged-in session from their ADFS system. In the behind-the-scenes hand shake, the CMS was to inherit user data and credentials through the SAML 2.0 protocol. So, if a Pratt user went to a protected page on the CMS, provided that they had successfully logged in to their ADFS based account, they would just get to where they were going seamlessly.
Solspace is primarily a LAMP stack development agency. We work for the most part in Craft CMS and ExpressionEngine. Often, when we have a difficult problem to solve for a client, that same problem has already been solved by other developers. This case of getting a LAMP stack CMS to talk to another system using the SAML 2.0 protocol is one problem that had already been solved multiple times by multiple developers. A PHP library for SAML 2.0 already existed; SimpleSAMLphp. We proceeded confidently, knowing that we just needed to find a way to get it to integrate with our client’s CMS as well as with ADFS.
Pratt’s ADFS server was of course behind a firewall. For security reasons, the domain of the server the CMS was running on would need to be whitelisted in order to allow communication. The two systems would also need to agree on the same language to use, this was SAML 2.0. The last bits pertained to encryption tokens and the like which would allow the two systems to make a secure hand shake. Through some trial and error we set these bits up.
In the spirit of reusing the work of other smart developers, we also intended to execute our initial concepts and code by integrating with Okta. Okta is a Single-Sign on service provider used by many large and small companies. We had worked with it before on a project with Sonos where we integrated their Craft CMS with their Okta based SSO system. We figured if we could get our code to work with Okta it would not be too far of a stretch to get things working with ADFS.
Through research, we discovered a method allowing us to completely control the ADFS configuration along with the whole Windows stack. We could also see all error logs and traffic. We could test and tweak both sides of the system until we hit on the exact formula that would allow the systems to work together. ADFS was the prime variable and using Azure to see everything about both sides of the house ended up being the critical piece.
There are two sides of the house with a SAML 2.0 integration; the IDP side and the SP side. The IDP is the Identity Provider. It is the source of the user credentials. The SP is the service provider. There can be as many SPs as there are systems that need to allow user access. In our case the Pratt ADFS server was the IDP and our ExpressionEngine CMS instance was the SP. Our SimpleSAMLphp configuration needed to correctly declare the definitions of our service provider.
When things get sticky in software the best approach is a systematic process of elimination. It all hinges on access to good feedback from the system. Once we had our own Azure based ADFS instance we could easily see that we were not telling the Pratt IDP what it needed to know about our SP. Once we corrected that, namely by making sure that our ‘entityId’ was correctly indicated in our configuration, everything fell into place.
This SSO integration project for Pratt Institute serves as an excellent example of what we call Creative Development at Solspace. We find a nice big problem, communicate carefully with our clients about it, collaborate creatively, and develop solutions iteratively until find the sweet spot.
We really love a good juicy problem, and we find joy in working together to come up with an elegant solution. We strive to be just as good at partnering with our clients as the technical parts of what we do. And, we generally have a lot of fun along the way.