This is part 1 of a 2 part blog series.
Small to medium development teams have had their head in the clouds for a while – and you know I’m not talking about the fluffy white stuff in the sky. Hosted services have the ability to offer value by removing the pain associated with installing, maintaining and upgrading applications.
JIRA Studio is Atlassian’s response to the demand for a complete hosted development suite offering our issue tracker, wiki, continuous integration, code inspection and review tools, together with source code hosting. With development in the cloud, you spend less time worrying about the infrastructure and spend more time building the cool stuff you love.
In terms of hosted messaging and collaboration, Google is a giant that’s second to none. Google Apps provides mail, calender, documents and chat services for businesses and educational institutions.
The decision to partner with Google Apps to to create a more collaborative software development suite was a no brainer! So how did we get Google and JIRA Studio to play nice?
Authentication With OpenID Single Sign-On
Authentication on the web has generally been implemented by a user knowing a secret that they have entered when they signed up for access to a particular service. This comes in two bits: a username and a password. This has led to users needing to maintain a separate account with each online service. Some service providers, like Google and JIRA Studio, use cookie/session-based authentication schemes so that when a user logs in to an application on a particular domain they share their authentication context with other applications on that domain. For example, you only need to log in to Google Mail once to be logged in to the whole suite of Google applications including Google Calendar and Google Docs.
What would be awesome is if you could share authentication contexts across the web, so that if you had an account with Google then you wouldn’t need to authenticate using a different account with JIRA Studio. This isn’t exactly a new concept – it’s been implemented in the past using proprietary protocols by enterprise vendors such as IBM and Novell and has also been standardised in complex security frameworks such as SAML. Rather than invent another solution, Google have opted to use an open format for delegated authentication that’s rapidly becoming the de facto standard: OpenID.
The basic idea behind OpenID is that a user can delegate authentication to a server responsible for handling authentication. Instead of having to maintain separate passwords for each service, services that support OpenID login can delegate the actual authentication process to another server. So you never need the user entering their password on your site.
Traditionally, OpenID authentication would require the user enter an OpenID identifier to log in to a site. This identifier usually takes the form of a URL that can be used to uniquely identify the user on a particular OpenID authentication server. The OpenID identifier select option in the OpenID 2.0 protocol allows the user to provide a generic URL pointing to their OpenID authentication server, rather than a URL that uniquely identifies them on the server. Since a JIRA Studio instance is tied to a specific Google Apps domain, we know the OpenID authentication server (OpenID Provider) URL for all users on the Google Apps domain. This means our users don’t need to enter a thing on JIRA Studio to log in.
The diagram below illustrates the execution of the protocol at a high-level. The clear win here is the end-user experience:
If the user is already logged in to Google Apps for their domain, then they can by-pass the Google login screen entirely and be authenticated as the same user in JIRA Studio. The end-user can be completely oblivious to the underlying authentication protocol and experience Single Sign-On across apps.
If the user is authenticating for the first time, then an account needs to be created in JIRA Studio so that the user can create issues, wiki pages and interact with the system. The sweet thing is that Google have implemented the OpenID Attribute Exchange extension to provide basic details about the user including:
- first name
- last name
- email address
These details are then used to automatically create a corresponding account in JIRA Studio. It’s almost too easy
The basic OpenID workflow can be implemented pretty swiftly using the OpenID4Java libraries. There are also implementations of the OpenID protocol in PHP, Python, C# and other languages.
However, all is not fun and games. There are a few subtleties that arise when delegating authentication:
- Single Sign-On (SSO): under the covers, when a user is authenticated into JIRA Studio via OpenID, JIRA Studio maintains a session to know that subsequent requests to JIRA Studio do not need further authentication. If this wasn’t the case, each request would have to be authenticated via the OpenID dance, involving a series of redirects, which would introduce noticeable lag. The downside of using a separate session is that you cannot implement Single Sign-Out: if a user signs out of Google Apps, they will still be signed in to JIRA Studio until JIRA Studio’s session times out. The converse is also true. It may be possible to implement single sign-out in the future if Google provide logout hooks.
- User Base Synchronisation: once you have delegated authentication, you also want to delegate user management: when a user gets added, updated or deleted in Google Apps, this user is similarly added, updated or deleted in JIRA Studio. Using OpenID authentication alone, it is possible to add and update users when they authenticate, but it’s not possible to detect when a user is deleted from the Google Apps domain (since this user won’t authenticate again). In our implementation, we detect user deletion by using the Google Provisioning API. Currently this API only provides a mechanism to retrieve all the users on the domain, so we evaluate a diff to work out what users have been deleted from the domain. A more efficient implementation of this feature would be possible if Google were to provide an API to retrieve the changes in the user base since a certain timestamp. That said, if you have 100 users on your domain, the current user synchronisation process takes 2 seconds.
- Password-Based Authentication: although OpenID is the way to go for browser-based auth, it can’t be applied to non-browser-based services. For example, in JIRA Studio we are forced to require users to set up a JIRA Studio-specific password in order to authenticate RSS feeds and provide authenticated SVN access. Ideally you would want to be able to call a Google API to perform simple username/password authentication in this case, however such an API call is not available at this stage.
In part 2, I’ll explore Data Access with the Google Apps APIs. Stay tuned…