Single Sign-On (SSO) is nothing new. For years, people have been able to use their Google or Facebook IDs to sign into various sites around the web. OpenID started in 2005 and was not a new idea at the time. Even SharePoint and IIS have allowed a sort of federated access through the use of NTLM, which itself has been around since Windows NT 4.0 (last millennium!)

Setting up Single Sign On is like having the One Ring –
the power to rule them all, but it takes a volcano to forge it

It does seem somewhat unfortunate that after all this time, many of us are still logging in to each application we use. Separately. Many times a day. Most of them use the same username and password (and we’re still allowed to use insecure passwords at that). But as we move toward using more cloud services, you may find yourself using services that don’t necessarily have the same password – this can get confusing quickly! You need some way to enable those cloud services to use your “internal” (that is, what your organization has provided you) username and password to keep everything manageable. Luckily enough, such a service will also allow you to leverage single sign-on!

As we take a look at how this works, the assumption is that your organization has Active Directory and can use Microsoft’s Active Directory Federated Services (ADFS). This post assumes you have ADFS 3.0. The setup is still pretty similar if you’ve got Apache Directory Server or another directory service front-ended by Shibboleth. ADFS (or Shibboleth, if you have that) acts as both a proxy so those cloud applications can access your internal credentials, and as the One Ring that binds all your SSO applications together. Setting an ADFS (or Shibboleth) server up is outside the scope of this post, so find someplace else to get that info if you need it so we can start leveraging the excellent benefits of having SSO.

In a nutshell, your ADFS proxy sits between all your applications and where your credentials reside:

The magic glue that allows your applications to all talk to your ADFS proxy is SAML – Security Assertion Markup Language – and one of its requirements is that both ends of the connection are encrypted. If you’ve been meaning to put an application like JIRA behind a reverse proxy like nginx, here’s your excuse.

Now that the basics are out of the way, let’s move on.

Ain’t nobody got time

In pre-ADFS days, each application determined how long your session would last. For some applications, this would be a set amount of time like 8 hours. Other applications (think your bank website) boot you off after a certain amount of inactivity. Each application had its own system, and each system stood alone.

But now that ADFS is in the picture, it brings its own values to the party. At a high level, a SAML-enabled application now has 3 timeout values to contend with.

ADFS Timeouts

The two ADFS timeouts come in two flavors: the Global Timeout which affects all SAML-enabled applications (henceforth known as Relying Parties), and the Relying Party Timeouts which can be but is not necessarily a different timeout for all relying parties.

Since this difference has caused confusion for many, consider this: each relying party is a balloon. What’s a party without balloons, eh? Any one of these balloons could pop sooner than their neighbors. You never know – maybe one has a hole. Or the guy across the street is testing out his new high-powered laser pointer. Point is, there could be a lot of balloons. And a lot of Relying Party timeouts.

Global Timeout

There’s just one* of these. In our illustration, it’s the woman’s hand. If she lets go, the whole party is done. All the balloons float away, and nobody gets the benefit of already being signed in when switching applications.

In ADFS 3.0, there are 3 values that control this timeout. Only one of these values applies each time a user logs in.

  1. Regular ‘ole logins are controlled by the SsoLifetime property. By default, this is 480 minutes (8 hours). This is a session cookie, so if a user completely quits their browser, they are logged out.
  2. If a user ticks the Keep Me Signed In box on the ADFS login screen, they will be subject to the KmsiLifetimeMins property. By default, this is 1440 minutes (24 hours) and the cookie is persistent, so even if a user quits their browser they will remain logged in. Note that by default, the Keep Me Signed In option in ADFS is disabled and has to be enabled before someone can use it to log in.
  3. If the user is logging in from a Registered Device (i.e. Organization-owned machine that’s been specially configured in AD), the PersistentSsoLifetimeMins timeout applies, which is 10080 minutes (1 week) by default. This uses a persistent cookie, so a user remains signed in even if they quit their browser.

If you are really paranoid, you can disable the persistent cookies so that every time the user closes their browser regardless of login type, they are forced to log in again. This is accomplished with “Set-AdfsProperties –EnablePersistentSso False” in PowerShell, but take a good long look in the mirror before running this command.

*There are methods for using different timeout values for people inside your network and people outside your network. If you require this level of control, please read this lengthy blog post on the subject. And good luck to you; you’ll need it.

Relying Party Timeouts

Each relying party gets its own timeout value. Many balloons, many relying parties. Using default values, newly created relying parties will show their TokenLifetime value as 0, which turns out to be 10 hours (doesn’t make sense to me either). ADFS 3.0 is unfortunately poorly documented, so there doesn’t seem to be rationale for why this is. Anyway, it’s pretty simple to change the value of each relying party individually if you wanted to; “relying_party” below being replaced with exactly the name used to enable that particular relying party.

This value controls how long a particular relying party can be authenticated for before it needs to check the global timeout. This value can be set lower than the global timeout. For example, if it’s set to 30 minutes and the global timeout is set to 2 hours, the following timeline would occur:

  1. 0 minutes – user logs in to the application by entering their credentials (global timeout is 2 hours, relying party timeout is 30 minutes)
  2. 30 minutes – relying party timeout expires. Relying party makes an authentication call; since there are 90 minutes left on the global timeout, the user is sent back to the relying party without having to enter their credentials
  3. 60 minutes – relying party timeout expires. Relying party makes an authentication call; since there are 60 minutes left on the global timeout, the user is sent back to the relying party without having to enter their credentials
  4. 90 minutes – relying party timeout expires. Relying party makes an authentication call; since there are 30 minutes left on the global timeout, the user is sent back to the relying party without having to enter their credentials
  5. 120 minutes – relying party timeout expires. Relying party makes an authentication call. Global timeout has expired. User must enter their credentials

Application Timeouts

Each relying party (or application) that you enable SAML logins for will already have its own timeout values. Many SaaS applications like NewRelic will allow you to modify these timeouts, but some do not. Since we are heavy users of Atlassian products here at ITHAKA, we’ll examine the application timeouts more closely for JIRA and Confluence.

Pre-SAML Behavior

JIRA and Confluence have two separate timeout values, only one of which is used for any given login:

  1. Regular ‘ole login – by default, the session expires after 5 hours for JIRA or 1 hour for Confluence. This is a session cookie, so if a user completely quits their browser they are also logged out. The value for this is stored in <application-install>/atlassian-jira/WEB-INF/web.xml for JIRA and <application-install>/confluence/WEB-INF/web.xml for Confluence. Search for the session-timeout property; the value is minutes.
  2. Remember Me – users get this simply by checking the “Remember Me” box during login. By default, this does not expire for 14 days. It is a persistent cookie, so users remain logged in even if they quit their browser. To change the default value of this timeout, you would need to modify <application-install>/atlassian-jira/WEB-INF/classes/seraph-config.xml for JIRA or <application-install>/confluence/WEB-INF/classes/seraph-config.xml for Confluence and insert the following (values are stored in seconds):

SAML Behavior

We use the SAML SingleSignOn family of plugins for JIRA and Confluence to enable SAML in those applications. With SAML-enabled logins, JIRA and Confluence use the standard session timeout defined in <application-install>/atlassian-jira/WEB-INF/web.xml for JIRA and <application-install>/confluence/WEB-INF/web.xml for Confluence. Search for the session-timeout property; the value is minutes.

After the application session has timed out, any pageloads will result in an authentication request that gets redirected to ADFS.

Tying It All Together

Once you have an understanding of all the timeouts, you can adjust as necessary to get sessions as long as you need for particular applications. Here’s a flowchart to help you understand where to start looking for values to adjust. At the start of the chart, the user has just signed into an application.