Plugins - Simple HTTP Auth
Add to favoritessimple_http_auth
Need to secure a backend or two somewhere, but don’t feel like leveraging a huge, ungainly authentication engine? Don’t care about putting a friendly face on the login screen?
Welp, you want simple_http_auth. It wraps around just the right amount of the Basic HTTP Authentication scheme (RFC 2617), and allows you to easily integrate it into your application, instead of making you adapt your code to my authentication scheme.
(Digest Authentication, Basic Authentication’s grown-up older sibling, is not supported here, because Microsoft effectively spiked it by releasing IE6 and IIS 5.0 with a super magical pony implementation of Digest Authentication which, surprise surprise, totally doesn’t work with Apache, and I’m not in a mood to meet standards-breakers halfway. If you don’t want passwords floating through teh intarweb in plaintext, use SSL. And slap the IE6 dev team if you see them.)
Usage
Overview
- Install the plugin. (See previous section)
- Add authentication requirements to your controllers as you see fit.
- Ride a bike instead of driving your car.
Specifics
simple_http_auth has one method: requires_authentication. To wit:
class PuppyHeavenController < ApplicationController
requires_authentication :using => lambda{ |username, password| username != 'cat' }
# ... actions go here ...
end
requires_authentication takes a hash of options as its lone argument, only one of which is mandatory: :using. :using is the event handler for any authorization attempt, and is passed two arguments: the username and password provided by the user during their login attempt. :using can be a Proc, as in the example above, or a String or Symbol referencing one of the controller’s methods. For example:
class PuppyHeavenController < ApplicationController
requires_authentication :using => :authenticate
# ... actions go here ...
private
def authenticate(username, password)
return username == 'dog' && password == 'woof'
end
end
The event handler for :using should return a Boolean value: true if the user is authorized to access the action, false if not. simple_http_auth doesn’t maintain your user database, make you use a specific model or controller, or anything. You’re responsible for all that.
By default, requires_authentication protects all of the controller’s actions, but this behavior is modifiable by using the :except and :only options:
class PuppyHeavenController < ApplicationController
requires_authentication :using => lambda{ |username, password| username != 'cat' },
:except => [:publicly_accessible_action]
# ... actions go here ...
end
or
class PuppyHeavenController < ApplicationController
requires_authentication :using => lambda{ |username, password| username != 'cat' },
:only => [:totally_secret]
# ... actions go here ...
end
Other options include:
:realm — the authentication "realm," which is usually displayed in the browser’s login dialog. Defaults to "Login Required".
:error_msg — the message displayed on an unsuccessful access attempt. Defaults to "401 Unauthorized: You are not authorized to view this page."
Logging Out
Occasionally someone may want to exit your wonderful application, but I wouldn’t know why. To enable these backsliders (or users in internet cafes, at work, on their sister’s computer, whatever), simple_http_auth provides for logging out:
class HappyMagicController < ApplicationController
requires_authentication :using => :whatever,
:logout_on => :logout
def logout
# logout.rhtml will be displayed after the user logs out
end
end
Using HTTP Authentication On Hosting Services
If you’re like most people, you’ve got a little corner on a shared host somewhere, and your Rails apps get managed by someone else. If that’s the case, you make need to jump through a few hoops to get HTTP authentication working. Some virtual hosting configurations of Apache, for example, don’t pass HTTP authentication headers to FastCGI applications like Rails, so you’ll need to add the following line to your public/.htaccess file if HTTP authentication doesn’t appear to work:
RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
(This is guaranteed to work on Dreamhost, but I’m not sure about others. Email me with details if you get it working in other environments and need to change this.)
There is another option which influences how simple_http_auth gets the user’s login and password:
:at — an array of header fields where the user’s login and password can be found. Defaults to [‘REDIRECT_REDIRECT_X_HTTP_AUTHORIZATION’, ‘REDIRECT_X_HTTP_AUTHORIZATION’, ‘X-HTTP_AUTHORIZATION’, ‘HTTP_AUTHORIZATION’], which should cover just about everything. These are tried in order, from first to last, and the first header which exists is used as the authentication data. If you’re getting a login dialog, but nothing seems to let you log in (and you’re damn sure your :using handler is working), try fiddling with this to make sure it’s actually receiving the data. For example:
class PuppyHeavenController < ApplicationController
requires_authentication :using => lambda{ |username, password| username != 'cat' },
:at => ['WOW-WHAT-A-STRANGE-HTTP-SERVER-YOU-HAVE']
# ... actions go here ...
end
Credits
Written by Coda Hale .
Released under the MIT license (see MIT-LICENSE).
Thanks to my employer, both for paying me to work with Ruby and Rails on a daily basis, and also for allowing me to release code which I developed for them.
http://blog.codahale.com/2006/05/11/basic-http-authentication-with-rails-simple_http_auth/
http://svn.codahale.com/simple_http_auth
Rails' (MIT)
Security

I think this is implemented in the current version of rails. http://weblog.rubyonrails.com/2007/9/30/rails-2-0-0-preview-release/comments/17383
class PostsController < ApplicationController USER_NAME, PASSWORD = "dhh", "secret"
end
Thanks! The rewrite rule works for gpcom.de, too.
I can use this auth system easily on my MacBook using MAMP. But it is using MySQL 4.x. My server is running Apache 1.x and MySQL 5.x. The authorization doesn't work on the server. Can you shed any light?
The authorization basically checks the username and password against a database table. The password is stored as plain text and not encrypted.
Thanks!