xmlrpc authentication

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