Wednesday, June 6, 2007

Progress on acts_as_authenticated and authorization in Rails

I'm happy to say I fairly quickly was able to implement authentication using 'acts_as_authenticated', a Rails plug-in. Props to the helpful Rubyists of Second Life for turning me on to that. I prefer the plug-in model to the engine model, much easier for me to grok.

So the steps were fairly simple. First, I went and grabbed acts_as_authenticated, per the helpful instruction page. If you have not tried a plug-in, it's worth it to do a bit of background to understand what is happening, I'd suggest the link-fest on the Rails Wiki as a primer. This gives you a basic database user repository. Then you can, in your controller, say things like:

class RolesController <>

before_filter :login_required

This filter will divert to a login page, along with signup, logout, password hashing, and other basic facilities. Badda-bing, badda-boom. Note that you can exclude various controller actions from the login requirement, so you can have guest pages, and other non-critical data in plain view.

Important to note, acts_as_authenticated only does the authentication part, so you need to go the extra mile to add authorization. There are a couple advertised plug-ins that sit on top of acts_as_authenticated, and I took a stab at the acl_system (actually, I grabbed acl_system2 out of SVN). The files and directories from acl_system2 go in your vendor/plugins directory in your Rails application. There are also a few pre-reqs to using the acl_system, as explained in the instructions:

You will need to have a current_user method that returns the currently logged in user. And you will need to make your User or Account model(or whatever you named it) have a has_and_belongs_to_many :roles. So you need a model called Role that has a title attribute. Once these two things are satisfied you can use this plugin.

So I created a role table in MySql, with id, title, and the usual created and updated dates. I added the following to my User model:

class User <>
has_and_belongs_to_many :roles

Along with this, I have a join table to link users and roles. Once this is configured, you can add additional filtering to the above authentication filter, as in this simple example:

class RolesController <>

before_filter :login_required
access_control [:list, :show, :new, :create, :update, :edit, :destroy, :index] => '(administrator)'

Note that this is simple, and the specification of complex action/role mappings looks fairly flexible. At any rate, it works in initial testing. Lots more to go, but this took much less time than grokking and implementing the user engine, YMMV, of course!

No comments: