The Problem

Over the years, I’ve seen a number of situations where Single Sign-On is necessary between applications, but no Commercial Off The Shelf (COTS) solution is available. This is often the case, because the COTS solutions are large, expensive, and require a significant amount of maintenance. Selecting and implementing a COTS solution is usually a company-wide decision and is not undertaken as part of some other, smaller project. However, this doesn’t lessen the frequent need for solid SSO solutions.

Many people try to follow standards of some type (SAML, etc) when implementing SSO, but this often leads right back to the problem of implementing a COTS product locally, not to mention that all SSO partners are required to support the same protocol and version. When dealing with external partners syncing up on SSO protocols and versions can be dicey at best.

To solve this problem, I’ve used a solution I call Simple Single Sign-On that uses a lightweight mechanism to create a cryptographically solid token that can be passed from one entity and validated by another. The system requires nothing more than the standard JDK on both sides as a prerequisite.

First, we’ll discuss what the SSO token must look like. We’ll then cover how a system can be built to create and evaluate those tokens. Lastly, we’ll talk about a few more necessary concepts for supporting the system.

Note: Attached to this post is a zip containing an implementation of the core of the system with the two necessary java keystores. The class itself, SSOUtil contains a main method that demonstrates using the creation and evaluation of the tokens. Download the source and keystores here.

The Token

Token Requirements

Now, let’s discuss what’s required in an SSO token. A valid token requires the following properties:

  • Non-repudiation: the receiver can validate from where/whom a message originates.
  • Message integrity: the receiver can validate that the message has not changed.

Both of the above characteristics are absolute requirements of tokens so that the asserting application can identify a user and then pass that identity on to the receiving application. It’s critical that the receiving party can be sure that it really is the asserting application “vouching” for the user listed in the token.

Enter Digital Signatures

The two properties discussed above can be provided by a digital signature. Digital signatures are made possible by public key cryptography. The key concept of public key cryptography is that the key used to encrypt a message is different than the key used to decrypt a message. This is where public-private key pairs come into play. The private key can encrypt a message and then the public key can decrypt the message and vice-versa.

Just encrypting a message with the private key can form a primitive digital signature. However, there are some security problems associated with just encrypting the message with a private key (i.e. forgery is in the realm of possibility). To address this issue, the message is first run through a cryptographic hash function and then the hash value is encrypted by the private key. The receiving application can then take the same hash of the plaintext and compare it to the decrypted (with the asserter’s public key) hash from the signature. If the two match, then the signature is verified. Note: to validate the signature, the receiving application must be able to access the plaintext message. The image from http://en.wikipedia.org/wiki/Digital_signature below describes this process well (click on the image to enlarge):

Digital Signature Operation

Token Transmission

A safe transmission of the token requires the following properties:

  • Message confidentiality: only the sender and receiver can read the message. No external third-party can recover the message.

It is important to keep the token a secret so that third-parties are unable to intercept the token in transit and use it to impersonate the user. If the transmission is not occurring behind a firewall, the best and most common way to achieve this is to transmit the token over an SSL connection (from a defense-in-depth perspective, it’s a good idea to transmit tokens over SSL even behind a firewall).

Token Uniqueness

There’s one more characteristic of a token that is important. The encrypted/signed token should not result in the same string every time for a particular user. If the token is the same every time, then the risk of the token being stolen becomes much, much higher as an attacker only has to steal the token once to be able to log in as the user until the theft is discovered.

To avoid this problem, we need to add in a timestamp to the message so that the encrypted part of the token is different every time. This accomplishes two goals:

  1. The created tokens are different every time
  2. Tokens can expire by having existed for more than a set amount of time.

About the Author

Object Partners profile.

One thought on “Simple Single Sign-On

  1. Bradford says:

    I’m kind of new to the SSO scene, but what’s wrong with CAS?

  2. Robert Kessler says:

    That is definitely the easier way than to have those super heavy systems

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
SwiftGen with Image & Color Asset Catalogs
You might remember back in 2015 when iOS 9 was introduced, and we were finally given a way to manage all of our assets in one place with Asset Catalogs. A few years later, support […]
Managing your Helm deployments with Helmfile
As we’ve been using Kubernetes to build software delivery platforms for our clients, we’ve found Helm to be a reasonable solution to templating and managing deployments to Kubernetes.  Although templating alternatives such as Kustomize have […]
AWS CodeBuild Test Reports for Gradle builds
Although AWS documentation has instructions for adding Test Reports for a maven build they currently lack instructions for a gradle build. You can find the maven instructions here: https://aws.amazon.com/blogs/devops/test-reports-with-aws-codebuild/ Assuming you have your gradle wrapper […]
Structuring SwiftUI Previews for API Calls
SwiftUI, together with Combine and Xcode 11+, provide a powerful toolset for quickly creating an app with a native UI. In Xcode 11+, the preview pane was introduced in order to provide live snapshots of […]