Monday, September 15, 2008

HTTP authentication and Rails

There are situations where a Rails application is almost complete, only lacking the users-authentication aspect. In such situations, sometimes elegant/complex authentication schemes are not really needed. For example, consider a simple administration panel that is developed for managing another application. In such a case, HTTP basic authentication could be very handy.

HTTP basic authentication doesn't rely on cookies like the casual session scheme. It simply depends on the fact that the client will send all its requests accompanied by an authorization header that represents the username and password. Web browsers implement HTTP basic authentication in a comfortable way. When a user requests a page that requires HTTP authentication, the response status is 401 unauthorized. the browser automatically detects this status and prompts the user for a username and password. The browser then repeats the request after adding the authorization header, and remembers adding it to all subsequent requests to the same domain name. Hence, a session is emulated.

Rails provides a very handy way for implementing HTTP authentication as a new aspect. The method authenticate_or_request_with_http_basic extracts the username and password from the authorization header and passes to the given block as parameters. By applying a before filter as the following, a simple HTTP authentication can be added to a complete Rails application as a new isolated aspect:

def authenticate_admin
authenticate_or_request_with_http_basic do |username, password|
admin = Administrator.authenticate(username, password)
if admin.nil?
render :text => "", :status => :unauthorized
return false

where Administrator.authenticate returns an admin from the database if username and password match any, and nil otherwise.

No comments: