atmos.org

getting better at software

Merb OpenID Consumer Application based on Merb-Auth

Posted on | October 30, 2008 | 4 Comments

We’ve been playing around with openid this week so I figured it was worth spending some time to test the latest merb 1.0 release candidate.

Say hello to the merb-openid-example app. It is a simple openid consumer application based on merb-auth. One of merb-auth’s built in strategies is openid, getting things going is simply a matter of enabling the appropriate authentication strategies.

This application is intended to run against merb 0.9.12(1.0rc4). Here’s a quick checklist of what was involved in getting merb-auth working with the openid strategy.

  • sudo gem install merb
  • setup the merb-auth strategy
  • add the openid and signup named routes
  • modify the user model to handle openid attributes
  • add the ensure_authenticated before filter

 
To setup merb I normally uninstall every trace of merb that’s on my system. The 0.9.x branches tend to conflict if you have multiple merb versions installed. I tend to do the following(note it uninstalls ALL merb gems):
gem list merb | awk '/merb/ {print $1}' | xargs sudo gem uninstall -aI
Then I just install the merb meta package
sudo gem install merb

Setting up the merb-auth strategy requires you to familiarize yourself with the merb/merb-auth/strategies.rb file. In a newly generated merb application this file should setup a salted password base authentication scheme, we want to change it so it looks like the following:

Next we need to setup two named routes that the openid auth strategy will use in order to make the openid authentication happen. I created a separate controller(authentication.rb) to handle these requirements. All you really need to know about the two named routes, openid and signup, is that signup should not require authentication and the openid route should.

The default user.rb that you get from merb-gen will need a few minor adjustments to work with openid. First you’ll have to add a few attributes if you intend to cache them locally, and after that you’ll need to disable the password validations that are automatically enabled by the salted password strategy(even if you disabled it). My user.rb looks like this.

Once all that’s done you should be able to just throw the before filter into your application.rb and you’ll be ready to start using merb-auth with the openid strategy.

The example application works outta the box, just run the merb command. It also has specs which show off a bug that still exists in rc4 where controllers are not honoring :o nly/:exclude parameters that are passed to before filters.

I’d like for this to remain a simple app that we can keep as a community example. If this gets outta date please fork it and send me a pull request on github.

Comments

4 Responses to “Merb OpenID Consumer Application based on Merb-Auth”

  1. Dan Kubb
    October 31st, 2008 @ 2:53 pm

    Thanks for this article. I’m just going through the process of trying to use Merb-Auth cascading strategies, one of them being OpenID and this is perfect timing.

    In the past I’ve always just rolled my own, but I wanted to stay as close to the “Merb-Auth way” as possible.

    In working with this tho, I did notice the abstraction that’s currently there is a bit strange. For example, the code within the index action (which is the OpenID endpoint) is only executed when the user is known, but if they aren’t Merb-Auth will redirect them to your signup action.

    I’m not entirely sure this extra redirect is necessary for OpenID auth. I think it may be a bit of a “leaky abstraction” and only required for Merb-Auth. What do you think?

    I also found the names of the routes a bit strange too, it’s not at all apparent what their purpose is. :signup is likely to be “reserved” in most apps, and “:openid” isn’t too clear. Something like “openid_endpoint” and “openid_register” would probably be better, but that’s open for debate.

  2. Dan Kubb
    October 31st, 2008 @ 9:51 pm

    OK, I probably shouldn’t have spoken before I had fully gotten everything working. I see now how the two actions work.

    I think my confusion came in because the “url(:openid) action” was doing double duty — it’s what you initially POST your OpenID login form to, and then you return to the same action after authenticating with your provider.

    I still wonder if that extra redirect to create the user account, if one does not exist, is necessary. I assumed prior to starting out on this that it would create the user (if they didn’t exist) with an overwritable method, not a full fledged HTTP redirect.

    BTW: Here’s my controller and supporting files that I derived from your work: http://gist.github.com/21471

    After alot of thought I ended up naming the actions “login” and “register”, and if I had a choice I’d rename those named routes to openid_login and openid_register.. assuming there wasn’t a way to factor that registration step into an overwritable method as mentioned above.

  3. Daniel Neighman
    October 31st, 2008 @ 10:25 pm

    Hey Dan,

    Just to follow up with this one. There needed to be “something” in place for when the openid is found but no user is in the system. That’s all the current behavior is. Something reasonable.

    There’s a whole bunch of callback methods on the openid strategy.

    These callback methods are supposed to be overwritten if they’re not to your liking. Here’s the “default” success method.

    http://github.com/wycats/merb/tree/master/merb-auth/merb-auth-more/lib/merb-auth-more/strategies/basic/openid.rb#L64

    I’m more than happy to accept feedback or patches for making this solid and easy to use.

    Thanx for taking the time guys to put this up :) Awesome

  4. atmos
    November 1st, 2008 @ 9:10 am

    You guys fucking rock.

    It turns out the bug that was present with :o nly/:exclude was related to my class name choice of Authentication for the controller. I applied all of Dan’s suggestions to the example and magically the app is completely working on 0.9.12.

Leave a Reply