Rails Two-factor Authentication

Given the problems passwords pose, isn't it time to offer people a second authentication factor? Your bank does it. Google does it. Even games do it. You can too. How hard is it to get Rails set up with a one-button six digit authenticator? Not hard at all! The hardest part was knowing where to look and what to get.

Close inspection of the dongles we already have revealed one name printed on them all: VASCO. VASCO provides the physical token you hold in your hand. We ordered a few of these. VASCO also provides the server software to authenticate tokens. The software comes in all sizes: enterprise, cloud, but for us the perfect match is just a C API called the VACMAN Controller. It runs on Windows, Linux, some more exotic OSes, but not Mac OS X.

How does it work? Each token has a serial number and contains a clock. When you press the button, the token shows a six digit one-time password based off that clock. Send the serial number, the password, and a little magic to the C API. It returns whether everything matches up right now. (So the clock on your server better be on time.)

How does the C API know whether the serial number and password match? In the beginning, VASCO creates a special encrypted file for you. It records how the clock and the serial number are synchronized. Before anyone can use their tokens, you have the API import the special file. It returns a data-structure with authentication information. Pass this magic struct with the serial number and password when authenticating. After authenticating, the data-structure is updated. Besides simple statistics like number of successful authentication attempts, the data structure stores information about token's internal clock. This allows the API to compensate for gradual time drift. The API itself is stateless. It's your job to keep track of the tokens and the data-structure.

Okay, but how does it work with Rails? As always, apply a little bit of glue. SWIG makes wrapping C APIs easy. This time was no exception though we did need to do a little more to allocate and free data-structures than usual. For the database, use ActiveRecord if that's your thing. We went with Sequal. We used two tables:

  • One table maps user names to token ids.
  • The other table maps token ids to magic data-structure blobs.

That's it really. We just use a script to import the import the token info. We don't use enough tokens to try to automate further.

Posted by william 15 Nov 2012 at 02:07AM


Use the following link to trackback from your own site":