XMLRPC Authentication

Troy Melhase troy at gci.net
Fri Jun 6 15:48:13 EDT 2003


Justin:

Here's a class that I use to do this with older versions of xmlrpclib.  It's
hack-around that I haven't really looked at for months, but it might be a
good start for you.


import base64
import xmlrpclib

class BasicHTTPAuthTransport(xmlrpclib.Transport):
    """ xmlrpclib.Transport subtype that sends Basic HTTP Authorization

        This subclass recognizes xmlrpclib versions '1.0.0' and '0.9.8' and
        adjusts accordingly during class definition.  Using any other
        version of xmlrpclib will raise an exception.
    """
    user_agent = '*py*'
    credentials = ()

    def send_basic_auth(self, connection):
        """ Include HTTP Basic Authorization data in a header """
        auth = base64.encodestring('%s:%s' % self.credentials).strip()
        auth = 'Basic %s' % (auth, )
        connection.putheader('Authorization', auth)

    if xmlrpclib.__version__ == '1.0.0':
        ## override the send_host hook to also send basic auth
        def send_host(self, connection, host):
            xmlrpclib.Transport.send_host(self, connection, host)
            self.send_basic_auth(connection)

    elif xmlrpclib.__version__ == '0.9.8':
        ## override the request method to send all 
        ## the normal and plus basic auth
        def request(self, host, handler, request_body):
            import httplib
            h = httplib.HTTP(host)
            h.putrequest("POST", handler)
            h.putheader("Host", host)
            h.putheader("User-Agent", self.user_agent)
            h.putheader("Content-Type", "text/xml")
            h.putheader("Content-Length", str(len(request_body)))
            self.send_basic_auth(h)
            h.endheaders()

            if request_body:
                h.send(request_body)
            errcode, errmsg, headers = h.getreply()
            if errcode != 200:
                raise xmlrpclib.ProtocolError(host + handler, errcode, \
                    errmsg, headers)
            return self.parse_response(h.getfile())

    else:
        ## don't know what to redefine
        raise TypeError("Unrecognized xmlrpclib version: %s" % \
             (xmlrpclib.__version__, ))

(Please excuse the formatting if it comes thru wrong -- my mail reader is
uncooperative today)

Use the class like this:

>>> auth_tran = BasicHTTPAuthTransport()
>>> auth_tran.credentials = ("joe", "secretpassword")
>>> srv = xmlrpclib.Server("http://host/xmlrpc/path", transport=auth_tran)

-troy

Justin Johnson wrote:

> I have a simple xmlrpc server (using xmlrpclib) that accepts requests
> from clients and runs some administrative commands on a bunch of servers
> I support.  I would like to lock down access to the service so that only
> authorized users can use it, by authenticating with a user name and
> password.
> 
> Has anyone done this before?  Is there an already existent authentication
> framework available I can use with xmlrpc?
> 
> I was looking at twisted, and they do have an authentication framework,
> but it looked like it wouldn't work with xmlrpc.  I'm trying to verify
> this with the twisted developers as well.
> 
> Thanks.
> -Justin





More information about the Python-list mailing list