FullStack Labs

Please Upgrade Your Browser.

Unfortunately, Internet Explorer is an outdated browser and we do not currently support it. To have the best browsing experience, please upgrade to Microsoft Edge, Google Chrome or Safari.
Upgrade
Welcome to FullStack Labs. We use cookies to enable better features on our website. Cookies help us tailor content to your interests and locations and provide many other benefits of the site. For more information, please see our Cookies Policy and Privacy Policy.

Getting Started with Single Sign-On

Written by 
Doug Roush
,
Principal Software Engineer
Getting Started with Single Sign-On
blog post background
Recent Posts
Choosing the Right State Management Tool for Your React Apps
Accessibility in Focus: The Intersection of Screen Readers, Keyboards, and QA Testing
Integrating GitHub Actions and Docker for a Java Project

In this article, I will go over the basics of Single Sign-On (SSO) and provide insight into some common features and technologies in the field. I will compare and contrast the strengths and weaknesses of the different approaches.

Table of contents

As its name implies, Single Sign-On (SSO) allows users to securely authenticate their identity and access multiple applications with a single set of credentials. This is advantageous for several reasons:

  1. Users don’t need to have separate logins/passwords for each application meaning they are less likely to forget their passwords and ask for help resetting them.
  2. SSO centralizes sign-on which makes auditing much easier.
  3. Users only have to spend time repeatedly signing in for each application they access.
  4. Applications behind SSO don’t ever see any passwords so there is less chance for a data breach.

However, there are some downsides to SSO as well:

  1. If a user's SSO account is compromised, the attacker can gain access to all their applications.
  2. Any downtime for the SSO infrastructure will make all applications that depend on SSO unavailable.

Terminology

Before we get too deep into this, let's cover some of the common terminology of SSO: 

  • Authentication (AuthN)- This is used to verify a user’s identity and prove they are who they say they are.
  • Authorization (AuthZ) - This is used to check if a user’s permissions/role allows them to perform an action (typically on a resource).
  • Identity Provider (IdP) - An IdP is used to create, manage, and store users' identities.
  • Service Provider (SP) - An SP provides a service to a user. It doesn’t verify a user’s identity, it relies on an IdP for that.
  • Relying Party (RP) - This is typically an application that will authenticate and authorize users (to an OpenId Provider) before allowing them access to resources.
  • OpenId Provider (OP) - This is either a front end for an IdP or an IdP itself.

Implementations

Single Sign On (SSO)  is generally supported by applications that use SAML 2.0 (SAML), WS-Federation (Wsfed), or OpenID Connect (OIDC). Wsfed and SAML 2.0 were released in 2006 and 2005 respectively and are both a bit older than OIDC which was released in 2014. OIDC is built on top of OAuth2 (2012), the distinction between these two being that OIDC handles AuthZ whereas OAuth2 handles AuthN. Wsfed and SAML both handle AuthN and AuthZ. It should be noted that, while they differ in terminology, the protocols for Wsfed and SAML function in very similar manners. For that reason, I’m going to focus only on SAML going forward as that is the more predominant technology between Wsfed and SAML.

How they work

SAML

SSO with SAML can be IdP-initiated or SP-initiated. With IdP-initiated SSO, you would login to the IdP login page (i.e: Google, Microsoft, Facebook). After verifying the user's identity, the user would be redirected to the SP. With SP-initiated SSO, you would arrive at the SP, then be redirected to the IdP. After verifying the user’s identity, you would be redirected back to the SP. 

SAML communications happen using assertions which are written in XML. The SAML protocol defines three types of assertions:

  1. Authentication - Provides information about a successful authentication attempt. 
  2. Authorization decision - Provides a decision whether or not a user can access a resource.
  3. Attribute - Provides a list of claims/groups that a user has/belongs to

OIDC

SSO with OIDC can only be RP-initiated. With RP-initiated SSO, you would arrive at the RP, and be redirected to the OP. The OP would then communicate with the IdP and return to the RP. 

As part of this communication the OP will return a JSON Web Token (JWT). A JWT is a set of claims. JWTs are much simpler than SAML assertions and not meant to be a replacement for them. JWTs are designed to be smaller so they can be passed around as URL parameters or cookies. If the contents of a JWT are sensitive, they can be encrypted to protect this data. 

The OIDC protocol uses three types of tokens for authentication:

  1. ID tokens - After being authenticated an ID token is returned, this will provide information about the user and their profile. This can be cached to improve performance and prevent needing to reach out to the IdP every time you need this info.
  2. Access tokens - Access tokens are short-lived tokens used to indicate what type of access a user has to a resource. An access token is issued after authentication and authorization occurs. This token contains a list of claims which determine how the user can interact with the resource.
  3. Refresh tokens - These are long running tokens which exist to request access tokens. They prevent the user from needing to reauthenticate every time the access token expires.

Common Features

Multi-factor Authentication (MFA)

MFA is used to verify a user’s identity using multiple methods of login. Generally, a physical device such as a hardware token or a cell phone app is used as the second authentication method. This makes it much harder to compromise an account because a malicious attacker would need access to the user’s password and the authentication method form the physical device.

Federation

Federated Identity Management (FIM) is often confused with SSO. While SSO allows users to sign into multiple applications from the same domain, FIM allows users to sign across multiple domains that have established trust. Domains can have varying levels of trust between each other.

Access Controls

In terms of SSO, IdPs handle authorization for an identity. Identities can span multiple applications, so application-specific permissions must not be included here—IdPs return scopes (i.e: groups of claims) for a user. Scopes define what the client is authorized to access in terms of the identity. Permissions define what the user themselves are allowed to access. For example, a scope may state that “a user is allowed to view and edit documents, but not delete them”. Permissions would be responsible for checking if the specific documents a user wants to view edit is allowed (i.e: they can view/edit documents they created but they can’t view/edit documents created by other users).

Advantages/Disadvantages

SAML

The biggest advantage of SAML is its flexibility. However, flexibility comes at the cost of having a complex protocol. When compared to OIDC, SAML has stronger security. As SAML is an older protocol, there are a bunch of different flavors available as most instances of this have slightly different implementations. This means integrating with SAML might be more complex than it seems because the implementation may not work 100% the way you expect it to. And, due to its complex nature, SAML can be hard to troubleshoot/debug, especially when multiple IdPs are involved. SAML also requires a lot of configuration and coordination between IdPs and SPs. If any of this is configured incorrectly you can introduce security vulnerabilities. Lastly, SAML only covers browser use cases and doesn’t work for mobile devices or API gateway requests.

OIDC

The biggest advantage of OAuth is its simplicity. However, a simple protocol like this doesn’t do a great job of dictating how to do things. It introduces more open-ended problems for the implementer to decide how it will work. This can lead to ambiguity and being used incorrectly, and thus security vulnerabilities. OIDC supports a number of signing algorithms which in itself is nice, but not all of them are secure. You need to make sure that you only allow JWTs which are signed using the same algorithms supported by the OP. Another disadvantage of JWT tokens is that once you issue an access token, they are hard to revoke as JWTs are stateless. To mitigate this you should set a short expiration time when issuing access tokens.

Common Pitfalls

To summarize the points in this article, here are some common pitfalls while implementing SSO:

  • Putting application specific permissions into the AuthZ model instead of leaving authorization to scopes at the identity level. These protocols are not designed for app specific permissions. You will likely need to write a bunch of code to make this happen and you can easily back yourself into a corner, specifically around size constraints with JWTs.
  • Not checking to verify the integrity of Assertions/JWTs before accepting them. Need to ensure they haven’t been tampered, they are still valid, and that they were issued to this user by your IdP.
  • Not setting up MFA for SSO accounts. If an account is compromised, it will grant access to all applications that the user has access to. According to Microsoft only 1 out of every 1000 compromised accounts have MFA configured. 
  • Trying to implement your own solution without fully understanding how these protocols work. Security is hard to get right and someone has probably already solved the same problem as you. You may want to look for an off the shelf solution before attempting to implement something yourself.
  • Incorrect configuration/setup leading to an insecure implementation of SSO which can be vulnerable to exploits.
Doug Roush
Written by
Doug Roush
Doug Roush

Doug is a Principal Software Engineer at FullStack Labs from Phoenix, Arizona. With 14+ years working as a senior engineer, Doug has been instrumental in the development of multiple projects using React.js, TypeScript, Redux, Saga, Next.js, Docker, Apache, and several other technologies. He stands out for his above-and-beyond approach to software development and his forward-thinking strategies to increase project reliability.

People having a meeting on a glass room.
Join Our Team
We are looking for developers committed to writing the best code and deploying flawless apps in a small team setting.
view careers
Desktop screens shown as slices from a top angle.
Case Studies
It's not only about results, it's also about how we helped our clients get there and achieve their goals.
view case studies
Phone with an app screen on it.
Our Playbook
Our step-by-step process for designing, developing, and maintaining exceptional custom software solutions.
VIEW OUR playbook
FullStack Labs Icon

Let's Talk!

We’d love to learn more about your project.
Engagements start at $75,000.