The Ruby on Rails bunch seems Web coder centric – no surprise there. Seems Web people prefer form/session based authentication while Unix weenies prefer HTTP-Authentication. Ever tried to get past form based authentication in a script? It’s a pain.
There are some issues with HTTP-Authentication in most Web Application environments but usually you can hack it in.
For Ruby on rails you don’t even need to patch. Create a User Model with a username and a passwd row somehow like this:
require 'digest/sha1'
class User < ActiveRecord::Base
def passwd=(str)
write_attribute("passwd", Digest::SHA1.hexdigest(str))
end
def passwd
"*****"
end
def self.authenticate(username, passwd)
find_first([ "username = ? AND passwd =?",
username,
Digest::SHA1.hexdigest(passwd) ])
end
end
Then add this to your app/controllers/application.rb:
def authorize(realm='Web Password', errormessage="Could't authenticate you")
username, passwd = get_auth_data
# check if authorized
# try to get user
if user = User.authenticate(username, passwd)
# user exists and password is correct ... horray!
if user.methods.include? 'lastlogin'
# note last login
@session['lastlogin'] = user.lastlogin
user.last.login = Time.now
user.save()
@session["User.id"] = user.id
end
else
# the user does not exist or the password was wrong
@response.headers["Status"] = "Unauthorized"
@response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
render_text(errormessage, 401)
end
end
private
def get_auth_data
user, pass = '', ''
# extract authorisation credentials
if request.env.has_key? 'X-HTTP_AUTHORIZATION'
# try to get it where mod_rewrite might have put it
authdata = @request.env['X-HTTP_AUTHORIZATION'].to_s.split
elsif request.env.has_key? 'HTTP_AUTHORIZATION'
# this is the regular location
authdata = @request.env['HTTP_AUTHORIZATION'].to_s.split
end
# at the moment we only support basic authentication
if authdata and authdata[0] == 'Basic'
user, pass = Base64.decode64(authdata[1]).split(':')[0..1]
end
return [user, pass]
end
Now you can add before_filter :authorize to all of your controllers which need protection.
Tested with Webrick and lighttpd/FastCGI
Posted in c0re | No Comments »