A Mozilla Persona Plugin for CKAN

Logging into CKAN using Persona

ckanext-persona is a CKAN plugin that lets users login to CKAN sites using Mozilla Persona.

The Persona plugin adds a login using your email address option to CKAN’s login and register pages. As you can see in the screenshot above, CKAN’s traditional username and password login is still available as well.

When a user clicks on the Email button it opens a Persona sign in page in a popup window. After signing into Persona the popup window disappears and the user is taken back to CKAN and logged in.

Here’s a video of the login process:

This was quite a fun plugin to develop, it was one of the first plugins to use CKAN’s IAuthenticator plugin interface and it revealed some interesting limitations that could be addressed in CKAN.

The way it works is:

Logging into CKAN using Persona
  1. The user browses to the login page of the CKAN website and clicks on the Email button. The button opens the Persona sign-in page in a popup window.

  2. The user signs in to Persona using their email address, verifying that they are the owner of the email address. The popup window closes, returning the user to the CKAN site that they came from.

  3. Persona sends an Identity Assertion Certificate to CKAN, asserting that the user owns the email address. Some JavaScript belonging to the Persona plugin receives this assertion from Persona and posts it to CKAN’s login URL.

  4. CKAN’s Python code on the server receives a request to its /login URL with the Identity Assertion Certificate in the post parameters. CKAN must now handle this request and log the user in.

When a request is made to CKAN’s /login URL CKAN iterates over the active IAuthenticator plugins and calls the login() method of each, to see if any of them can handle this login request. If no plugin logs in the user, CKAN will fall back to its default username and password login handler.

After finding the Identity Assertion Certificate in the post params and verifying it, the Persona plugin’s login() method handles the login request as follows:

Logging into CKAN using Persona
  1. It searches CKAN’s database for an existing user account with the verified email address. There are three possible responses from the database:

    a. There is one existing CKAN user with the email address (this is what’s shown in the video above.)

    b. There is no existing user with the email address, so the plugin creates a new account with this email address and logs the user into it (this is done silently - the user isn’t bothered with the fact that a new account is created for them on the CKAN site).

    c. The CKAN site has multiple users with the same email address. In this case the plugin shows the user a list of the user accounts and asks them to choose which one they want to login to. (Note: this page isn’t implemented yet!)

  2. Whichever route we took, we end up with one CKAN account that matches the Persona email address that was used. The plugin logs the user into the account by saving the email address and username of the account in CKAN’s Beaker session. (The session is a file on the server that keeps track of the logged-in user.)

  3. Finally, the plugin redirects the user’s browser to the dashboard page of the account they’ve just logged in to.

On every page load, CKAN calls the identify() method of every active IAuthenticator plugin to see if any of them can find out which user is logged in. If no plugin identifies the logged-in user, CKAN searches for a cookie created by its default username and password login.

The Persona plugin’s identify() method will use user name it saved in the Beaker session to identify the user. This is how the user stays logged-in as they move from page to page on the site.

Finally, when the user hits the logout button CKAN calls the Persona plugin’s logout() method, which deletes the cookie that the plugin created so that its identify() method will no longer find a logged-in user when the next page is loaded.

Todo

A few of things still need to be implemented:

Other things that still need to be done include JavaScript-less login with Persona, CSRF protection, tests, a nicer user experience when the Persona verification fails, and enabling CKAN accounts to have multiple email addresses and verifying those addresses with Persona.

Mozilla recommend using Selenium to test logging in with Persona. We’ve been planning to use Selenium for new frontend tests in CKAN, so once we get going with that maybe we can write the ckanext-persona tests in the same way.

To test ckanext-persona, see the ckanext-persona website for installation instructions.