A while back I blogged about the flatirons openid provider and how it was inspired by something we were doing at Engine Yard. We needed a single sign on provider and chose to use OpenID as the sso protocol. Since this is heavily influenced by openid I will often use the word ”provider” to describe an SSO server. I also use the word ”consumer” to describe an SSO enabled application.
So we pretty much drew up a diagram of how openid works and removed the steps we felt were unnecessary(decision/acceptance steps). We then extended it by adding auto discovery of the openid url. Here’s a somewhat up to date diagram that shows off how things work. You’ll notice that the user-agent(browser) never specifies its identity url, it’s automatically provided from the SSO server.
I’m pleased to announce a new piece of software that might interest you if you need a single sign on solution for your projects. It’s called hancock and it’s available(like all good things) on github. Here’s a quick run down of what it offers you:
This is all implemented in about 400 lines of ruby code using the sinatra framework. With the release of Sinatra 0.9.1.1 programmers can write sinatra applications in a more modular fashion. The killer feature is that these modular applications are actually rack applications. This allows for services to be written in sinatra that can be deployed as either a standalone rack application or used as middleware in frameworks like merb or rails. Hancock is an example standalone rack application. I’ll be blogging about sinatra as middleware in the days to come.
Hancock requires that you provide atleast three things to get it going. This is normally provided in your rackup file.
Hancock assumes that you’re going to provide the layout that gives your site its customized look and feel. The hancock gem itself provides all of the forms for authentication. If you’re going to be serving static assets like images, stylesheets, or javascript files you’ll also need to set the public attribute. Here’s what my rackup file looks like on my server.
That’s your whole app.
The Hancock gem provides a sinatra application as a class named Hancock::App. You should inherit from this class and implement a landing page at ”/”. The mailer configuration functions a lot like the merb-mailer gem, if you’re having issues google around for merb-mailer help.
The Hancock gem also provides a class named Hancock::Consumer that represents a consumer application that is to be accepted by your hancock application. The :url attribute MUST match up to the return_to parameter in the openid negotiation. If you’re using the hancock-client gem then it should take care of this for you. The main thing to remember about this class is that if you ever receive the Forbidden message on your SSO provider you should double check that the host is allowed to access the provider.
Your user model is exposed as Hancock::User. Right now there is simple sign up through web forms. If you want to test the provider without setting up the full email configuration then you should run your application in development mode. When run under development mode the registration url that would normally be sent via email is embedded as a comment. I found that it made it really easy to test.
The Hancock gem doesn’t have perfect tests, but I’ll be damned if we aren’t shooting for it. You’ll find both unit and acceptance tests done in rspec, rack-test, webrat, and cucumber. Even if you’re not interested in an SSO server the tests might help clarify a few things if you’re a testing junkie.
As I mentioned earlier, the killer feature of sinatra 0.9.1.1 is that sinatra apps are modular rack applications. While hancock is a pretty cool example of the power and simplicity of sinatra; its use as middleware in other frameworks is where I expect to see sinatra shine for the foreseeable future. Even if you’re stuck on a never ending rails project with no chance of innovation in sight, go learn about rack. I think you’ll be surprised where you can start leveraging it. Besides, writing sinatra is fun.
So what good is a simple SSO server if you don’t have a super simple client library? I bet if we did it as a simple sinatra app then we could turn it into middleware. Then we could hook our rails and merb apps up. Yeah, that’d be sweet.
I’m gonna follow this up in the next few days with something covering the hancock-client gem. This gem provides a sinatra application that can be run standalone or as middleware in other apps. I’ll prolly follow that up with two short articles on “how you get your middleware running in (rails|merb).”