Hi all,
what is the recommended way to do user authentication for xmlrpc ruby on rails webservices?
Thanks, -Armin
Hi all,
what is the recommended way to do user authentication for xmlrpc ruby on rails webservices?
Thanks, -Armin
Use http authentication. Put this into lib/http_authentication.rb:
# From Peak Obsession with a few # minor fixes.
module HttpAuthentication
protected
def http_authenticate(realm=@request.host + ' Web Password', errormessage="Couldn't authenticate you") username, passwd = get_http_authentication_data # Check authorization unless username send_http_authentication_response(realm, errormessage) and return end user = User.authenticate(username, passwd) unless user && user.isremote? logger.info("sending auth response"); send_http_authentication_response(realm, errormessage) and return end # No session, so make this a class variable @user = user end
private
def send_http_authentication_response(realm, errormessage) response.headers["Status"] = "Unauthorized" response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\"" render :text => errormessage, :status => 401 end
def get_http_authentication_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? 'Authorization' # for Apace/mod_fastcgi with -pass-header Authorization authdata = request.env['Authorization'].to_s.split elsif request.env.has_key? 'HTTP_AUTHORIZATION' # this is the regular location authdata = request.env['HTTP_AUTHORIZATION'].to_s.split elsif request.env.has_key? 'Authorization' # this is the regular location, for Apache 2 authdata = @request.env['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
end
Then in the controller for your web service:
require_dependency "http_authentication"
class RemoteController < ApplicationController include HttpAuthentication wsdl_service_name 'Remote' web_service_api 'Remote' before_filter :http_authenticate session :off .... end
The only thing you probably need to worry about is the "user = User.authenticate..." part in the http_authenticate method. I use my regular user table, but with a type of "Remote". Then only those remote users may be used to get to web services, and non-remote users may not be used.
Michael