The way users have logged in over time has largely remained the same. Only the internal workings of this mechanism have been updated to become more robust and secure. From the user’s point of view, they still have to remember some kind of credentials and enter them every time they want to access an application.
In recent years, another type of authentication has become increasingly popular and has been adopted by more and more applications—SSO or single sign-on.
What is SSO?
From a developer’s point of view, SSO is when an application (service provider) relies on a third-party trusted application, known as an identity provider, to authenticate users. It works on the basis of a relationship of trust between the two parties in which the identity provider takes care of all authentication for the service provider and only passes on information the service provider needs.
This makes obsolete the need for the developer to implement an authentication system and also to manage and secure any private information of the user.
From a user’s point of view, SSO is when a user logs into an app once and is then automatically logged in to all the other apps that make use of the same SSO authentication mechanism.
How does SSO work?
SSO can be implemented with different protocols, like OpenID Connect, SAML and so on. Although the implementation works differently across different protocols, behind the scenes, the main idea is the same.
This entire process can be described step-by-step as follows:
On first login:
- Your application redirects the user’s request to the identity provider.
- The identity provider checks to see whether there is an existing SSO cookie.
- Because this is the user’s first visit to the app and the identity provider’s SSO cookie is absent in the user’s browser, the user is requested to log in using one of the connections configured by the identity provider.
- Once the user has logged in, an SSO cookie will be set and the user will be redirected to the application, with a token containing the relevant identity information of the user.
On subsequent access:
- Your application redirects the user to the identity provider’s page.
- The identity provider checks to see whether there is an existing SSO cookie.
- The identity provider finds the SSO cookie and checks if it is still valid or it has expired.
4.1 If it has expired then the user is redirected to the login page.
4.2 If the SSO cookie is still valid, the user is redirected to the application, with a token containing the relevant identity information of the user.
In both cases, the user’s first login and subsequent access, there can also be a step 5. The target application can use the token to retrieve the user information on its own or it can send a new request to the identity provider that contains the received token. The identity provider will then decrypt and send the user information.
What are the advantages of SSO?
To quickly spot one of the top advantages of the SSO system, imagine this scenario:
You are a customer who has been admitted to a bar but you are asked to show ID to prove your age every time you try to buy another alcoholic beverage.
This would be irritating for anyone because you understand that what you are doing is a repetitive process, which does not make much sense.
Now imagine that your friend was admitted to another bar that checks a patron’s id just one time and then serves the patron multiple alcoholic beverages throughout the day.
You can equate the second bar to a system that is based on authentication through SSO; rather than verifying the id several times, the user needs to verify their identity just one time and thereafter, they can access a variety of services.
Aside from being simplified and user-friendly, SSO is a great option because it is secure.
It’s a win-win scenario.
Same sign-on vs single sign-on
An SSO mechanism is called single sign-on only if, once you’re logged in, you can access all company-approved applications and websites without having to log in again. Apart from single sign-on, SSO can also mean same sign-on, which works more as a credential vaulting or password manager mechanism. With this mechanism, you may have and use the same credentials, but they must be provided each time you access a different application.
Why should you use SSO?
SSO is a great solution, but only for those who really need it.
This mechanism is a perfect solution when as an organization you have the same user base for multiple or even all your applications. This will not only give you speed, will also make the system easier to manage and secure because everything is centralized.
Imagine you are an organization, small or big, and you have different internal applications that are meant to be used by all of your employees. Instead of having separate authentication systems on each of these applications, you can have just one central system that will handle the authentication for each of your application.
If you want to deepen your understanding of an SSO system, here is how a basic one might be implemented at a core level.
We’ll write the code in NodeJS and it will use JWT as a mean of identifying users.
The mechanism will consist of two applications, the identity provider service and an adapter that can be used by back-end clients as a middleware.
Earlier, we saw that this authentication process is done based on some redirects that go back and forth between the two parties and the identity provider returns the information back to the target application.
To do so, we need to be able to send information along these redirects. The convenient way would be to use request headers, but this is not possible in the case of redirects as headers from the previous response are not added to the new request for the redirected location.
Therefore, we are left with two options:
- Place the information in the query string for the redirected URL as a parameter.
- Set a cookie.
In our example, we will use only the first option.
The Identity Provider
A simple setup for this service would look like this:
We have a basic express server that uses cookie-parser module to set and read cookies. We have also included the jsonwebtoken package as it will be used for creating JSON web tokens.
The identity provider must have access to our user base but, for the purpose of this example, we have hard-coded a user on the server. In a real-life scenario, this user would be replaced by a connection to the database from which users are retrieved. Also, the password would have been hashed???? .
Because this service will only take care of the authorization, the user information is brief. We only need to have access to the user’s credentials. If we are an organization and we want to easily identify users we can also assign each of them a unique identifier, a user id that will also be included here.
Users are redirected to a login page if they are not authenticated. The login system can vary based on the needs.
To keep things simple we used a classic email & password combination, which can be sent over a GET request.
Once the user is authenticated against the identity provider service, a request with his credentials are sent to the server along with a redirectUrl. This redirectUrl is the application that the user previously tried to access.
If the credentials match, then a long life token (1d, 12h) is issued that is stored in a secure way. This can be done using several cookie options, like httpOnly in our case, which will make it available only for the back-end code.
In our scenario, this token is valid for 1 day, meaning that once a user has authenticated against an application, he can use any other application that shares the same SSO mechanism for 1 day without being required to re-authenticate.
To complete this service, we need to add two more requests:
- the main request that will be used by the client to authenticate their user and emit a short life token that contains the user information
- another optional request that can be used by the client to decrypt the token and get the user information
The first request /auth will check if the SSO cookie was set. In case it was, the identity provider will emit a short live token that will be sent to the target application (consumer). Otherwise, it will redirect the user to the login page.
The second request /get-identity will decrypt the short live token and return the user information back to the target application.
The client adapter
The client adapter can be used as a middleware to protect the desired resources. This adapter will do the handshake with the identity provider where it will perform a redirect to the /auth endpoint to get the short live token with the user information and then it will do a GET request to decrypt that token and extract the user information.
This was a demo of a basic SSO system implementation to help you better understand this service. In a real-life scenario, SSOs can become more complex as other things need to be added to strengthen the security.
If you want to incorporate SSO into your application, you can start by looking at basic examples like this one and build on top of it. Alternatively, if you don’t want to have a dedicated solution, you can look at open source solutions like Keycloak or Shibboleth.