Basic Authentication

May 20, 2008 | Author: hassox | Publisher: hassox

Merb makes basic authentication for your application a piece of cake. Take a look at this for simple.

Basic API

There’s really only three methods in Merbs basic authentication module.

  1. basic_authentication
  2. authenticate
  3. request

You trigger basic authentication in your controller with a before filter.

Simplest Case

The simplest case is just to use the basic_authentication method. Here’s one way you can use it. class Posts < Application before :authenticate, :exclude => [:show, :index] protected def authenticate basic_authentication("My Realm") do |username, password| user == "hassox" && password == "sekrit" end end end

This very simple example applies basic authentication to all actions in the Posts controller except the show and the index actions.

It’s very simple and the success or failure of the authentication is the whatever the block evaluates to. So if you return false, the client will keep getting asked for their username and password.

Full Control Example

Sometimes you need a bit more though and Merb’s not shy in this situation. By using the other two methods you can give it some more power. Say we wanted to check the Database to see if a user existed (and had permissions).

class Post < Application before :authenticate protected def authenticate user = basic_authentication.authenticate do |username, password| User.authenticate(username, password) end if user @current_user = user else basic_authentication.request end end end

Hopefully it’s pretty simple to see what’s happening here. First, we check the User model for someone with the correct credentials. Then, if we find someone, we assign them to and instance variable and finish. If we don’t find anyone we request the client provide basic authentication credentials.

There’s really no more to it than that. Short and Sweet, but nice and flexible. You can check out the docs for this feature in Merb.

Comments

On May 22, 2008 at 04:40 jnicklas says:

If you need to specify the realm with ‘request’, you can do that like this:

basic_authentication("My Realm").request

The caveat here is that the realm is an argument to basic_authentication, not to request.

On June 17, 2008 at 02:08 inspired says:

This works fine, but if you try to request a format explicitly with .xml:

                 ~ A format (xml) that isn't provided (html) has been requested. Make sure the action provides the format, and be careful of before filters which won't recognize formats provided within actions. - (Merb::ControllerExceptions::NotAcceptable)
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/responder.rb:302:in `_perform_content_negotiation'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/responder.rb:331:in `content_type'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/render.rb:94:in `render'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/authentication.rb:76:in `request'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/authentication.rb:82:in `authenticate_or_request'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/authentication.rb:61:in `initialize'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/authentication.rb:51:in `new'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/mixins/authentication.rb:51:in `basic_authentication'
                /home/merb/freeswitch/app/controllers/sip_accounts.rb:163:in `authenticate'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/abstract_controller.rb:248:in `send'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/abstract_controller.rb:248:in `_call_filters'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/abstract_controller.rb:240:in `each'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/abstract_controller.rb:240:in `_call_filters'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/abstract_controller.rb:195:in `_dispatch'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/abstract_controller.rb:193:in `catch'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/abstract_controller.rb:193:in `_dispatch'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/controller/merb_controller.rb:189:in `_dispatch'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:126:in `dispatch_action'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:126:in `synchronize'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:126:in `dispatch_action'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:73:in `handle'
                /usr/lib/ruby/gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/connection.rb:59:in `pre_process'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/connection.rb:50:in `process'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/connection.rb:35:in `receive_data'
                /usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.0/lib/eventmachine.rb:224:in `run_machine'
                /usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.0/lib/eventmachine.rb:224:in `run'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/backends/base.rb:45:in `start'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/server.rb:146:in `start'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/controllers/controller.rb:79:in `start'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/runner.rb:166:in `send'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/runner.rb:166:in `run_command'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/lib/thin/runner.rb:136:in `run!'
                /usr/lib/ruby/gems/1.8/gems/thin-0.8.1/bin/thin:6
                /usr/bin/thin:19:in `load'
                /usr/bin/thin:19
                

On June 17, 2008 at 09:07 hassox says:

@inspired if you want to provide xml from your applications you need to specify it, and make sure that display can display it or you have a template for it.

Please see my tutorial on Providing Different Formats In Merb for more information on providing different formats in your merb application.

On June 17, 2008 at 13:39 inspired says:

Hi Hassox,

I have only_provides :xml for the action, which works fine both when I do http://site/controller_name/action_name, but as soon as I do http://site/controller_name/action_name.xml I get the error message above. If I remove authentication it works with both the .xml ending and without it and always provides xml, but with auth added it only works without .xml :-)

Possible merb bug?

Sign in to add your comment