Sinatra Basic Authentication - Selectively Applied
Most web applications have some sort of admin area where users shouldn’t be. Passwording it is the obvious solution, but it isn’t obvious how to implement passwords in Sinatra. I stole this code from Ryan Tomayko’s Wink blog, and extracted it into a more generic module for reuse. Two parts are involved, the module, which I put into a separate file, and include. And then the code itself to pull it into the helpers and use it in the event handlers.
The module:
module Sinatra module Authorization def auth @auth ||= Rack::Auth::Basic::Request.new(request.env) end def unauthorized!(realm="myApp.com") header 'WWW-Authenticate' => %(Basic realm="#{realm}") throw :halt, [ 401, 'Authorization Required' ] end def bad_request! throw :halt, [ 400, 'Bad Request' ] end def authorized? request.env['REMOTE_USER'] end def authorize(username, password) # Insert your logic here to determine if username/password is good false end def require_administrative_privileges return if authorized? unauthorized! unless auth.provided? bad_request! unless auth.basic? unauthorized! unless authorize(*auth.credentials) request.env['REMOTE_USER'] = auth.username end def admin? authorized? end end end
To use the module:
require 'authorization' helpers do include Sinatra::Authorization end get '/admin' do require_administrative_privileges # Do private stuff end
EDIT: Thanks to foca on #sinatra for the nicer setup of authorize
License: Because this was extracted out of Wink, follow the Wink license (found here).
July 17th, 2008 at 9:47 pm
I’d extract the credentials array into a separate method in the module. That way it can be overridden in the helpers block to allow people to include the module without the need to modify it :)
July 18th, 2008 at 12:24 am
Oh yeah! Rack is full of gems, it seems.
August 4th, 2008 at 7:43 pm
I’m a bit confused, how can those elements not be in a string?
Also, the first line of unauthorized! is giving me problems.
August 4th, 2008 at 7:44 pm
woops.. accidentally put an open span element in the last comment.
ment to say “span elements”
August 4th, 2008 at 7:55 pm
tolas: that’s wordpress being very dumb. Sorry about that.
August 7th, 2008 at 5:13 pm
hi
This doesn’t work for me
$ ruby privatestuff.rb
privatestuff.rb:1:in `require’: ./authorization.rb:9: syntax error, unexpected ‘;’ (SyntaxError)
header ‘WWW-Authenticate’ =>; %(Basic realm=”#{realm}”)
^ from privatestuff.rb:1
//
on ubuntu 8.04, ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]
August 7th, 2008 at 5:18 pm
ben, I am going to have to put this up on a pastie or something, since wordpress keeps messing with the formatting of certain entities mainly > and &. Just remove the semi colon and move on.
October 25th, 2008 at 8:14 pm
Hi,
How can I logout user using HTTP authentication?