Power of interfaces in Software Development
Hey folks, welcome back to another post in the SSO series of posts. Let me start with a quick question. Be it any language that you code in, how often do you write interfaces? I bet the answer for most of you would be ‘not many times’. Let me jot down briefly why interfaces are so powerful and how that benefited us in our customized SSO implementation.
What are interfaces?
Let's start with a quick intro about interfaces. Interfaces are basically an abstract definition of functionality. Interfaces define what the behavior of an object and subsequently a class would look like. Coding to interfaces is a widely used, well-known technique. It suggests creating an interface first, defining its methods, and then creating a class for actual implementation.
Interfaces provide a solid contract between the client and the application as to the behaviors the client can expect from the application. In addition to this, a few other benefits are as listed below,
- They provide a layer of abstraction that keeps the detailed implementation hidden from the user. Users of the interface can trust it to function as per the contact without worrying about the underneath implementation.
- Single interface declaration can have multiple implementations underneath utilizing a varied set of vendors or a different logic serving the same use case in different flavors.
- Maintaining backward compatibility is easier as the contract established through interfaces remains unchanged while the implementation underneath is enhanced.
- Interfaces enable Test-Driven Development (TDD). In absence of any implementation, interface declarations can be used to generate mocks that help in writing the tests.
Now that we are through the details about interfaces, let's talk about the issue we faced related to this and how a library interface enabled us to customize a particular behavior.
As mentioned in my introductory SSO blog, for our SSO implementation, we used a SAML library for handling the core workflows for SAML 2-based auth. We also know that the SSO auth workflow starts by making a request to IdP and upon successful authentication, the IdP responds with an encoded assertion response. With this information in hand, let's get into the details of the issue…
A vital aspect of SSO authentication is verification of the received assertion response from the IdP. Along with ensuring the integrity of the received response, it is important to verify that there was a valid authentication request that resulted in this response. The SAML library that we used in our implementation uses browser cookies to keep a track of this. However, we didn't want to go this route as we were facing issues with cookies as described by Klaus Nji in his blog. This is where INTERFACES came to our rescue.
The SAML library had exposed an interface of methods that tracked the SSO authentication requests. It was like below,
This allowed us to replace the whole persistence of tracking information in cookies with our own Redis persistence. The authentication request state during initiation was now being saved into Redis and the same was fetched during assertion response verification in order to verify the authenticity of the response received from IdP.
This was, fortunately, the final hurdle in getting the SSO authentication working. Wait! did I say final? Na.. not yet! The development of the feature was complete, but the testing was still pending. At Virtana, we use Cypress tests for testing user workflows. Read about the challenges we faced during that in my Integration Testing of SSO blog.
Until the next one….. Keep coding! 💻