Picnic::Authentication::Basic provides Basic HTTP Authentication for your Camping app. The
module defines a service
method that only continues the
request chain when proper credentials are provided by the client
(browser).
To activate Basic Authentication for your application:
Picnic-fy your Camping app (e.g: Camping.goes :your_app;
YourApp.picnic!
)
Call YourApp.authenticate_using :basic
.
Define an authenticate
method on your application module that
takes a hash. The hash contains credentials like :username
,
:password
, and :hostname
, although future
authentication modules may submit other credentials. The
authenticate
method should return true when the credentials
are valid. Examples:
module Blog def authenticate(credentials) credentials[:username] == 'admin' && credentials[:password] == 'flapper30' end module_function :authenticate end
or
module Wiki def authenticate(credentials) u = credentials[:username] p = credentials[:password] Models::User.find_by_username_and_password u, p end module_function :authenticate end
service
sets @credentials
to the credentials of
the person who logged in.
This code is based on Camping::BasicAuth written by Manfred Stienstra (see www.fngtps.com/2006/05/basic-authentication-for-camping).
Reads the username and password from the headers and returns them.
# File lib/picnic/authentication.rb, line 87 def read_credentials if d = %w{REDIRECT_X_HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION}.inject([]) { |d,h| @env.has_key?(h) ? @env[h].to_s.split : d } u,p = ::Base64.decode64(d[1]).split(':')[0..1] if d[0] == 'Basic' return {:username => u, :password => p} end end
# File lib/picnic/authentication.rb, line 95 def service(*a) app = Kernel.const_get self.class.name.gsub(/^(\w+)::.+$/, '\1') unless app.respond_to? :authenticate raise "Basic authentication is enabled but the 'authenticate' method has not been defined." end @credentials = read_credentials || {} if app.authenticate(@credentials) s = super(*a) else @status = 401 headers['Content-type'] = @headers['Content-type'] || 'text/plain' #headers['Status'] = 'Unauthorized' headers['WWW-Authenticate'] = "Basic realm=\"#{app}\"" @body = 'Unauthorized' s = self end s end