XML-RPC Server für Python mit SSL und Basic Authentication

Nachdem ich mit einigem Googlen und Quellen durchlesen es geschafft habe, einen XML-RPC Server inclusive SSL und Basic Authentication für Python zu erstellen, möchte ich es euch nicht vorhalten. Wer weiß, vielleicht sucht jemand gerade sowas :-)

Als Framework wird Twisted verwendet. Der Vorteil ist, dass das Framework bereits viel Arbeit abnimmt und schöner zu konfigurieren ist, als der Python eigene XML-RPC Server (meine Meinung!).

Zuerst brauchen wir ein Realm, welcher eine Resource für authentifizierte Benutzer zurückliefert. Wir wollen das ganz einfach halten und geben nur ein Objekt der Klasse zurück, die den XML-RPC Server darstellt:

class SimpleRealm(object):
    """
    A realm which gives out L{GuardedResource} instances for 
    authenticated users.
    """
    implements(IRealm)

    def requestAvatar(self, avatarId, mind, *interfaces):
        if resource.IResource in interfaces:
            return xmlrpc.XMLRPC, ServiceObject(), lambda: None
        raise NotImplementedError()

Dann brauchen wir ein “ServiceObject”, welches die Methoden für den Server implementiert:

class ServiceObject(xmlrpc.XMLRPC):
    def xmlrpc_test(self, year, month):
        return calendar.month(year,month)

Der Server macht nichts anderes, als einen Kalender für den angegebenen Monat und Jahr zurückzugeben.

Als letztes brauchen wir noch den Code, das alles zusammenbastelt und den Server startet:

if __name__ == ‘__main__’:
    checkers = 
        [InMemoryUsernamePasswordDatabaseDontUse(joe='blow')]
    wrapper = guard.HTTPAuthSessionWrapper(
        Portal(SimpleRealm(), checkers),
        [guard.BasicCredentialFactory('localhost')])
    if (SSL):
        sslCF=DefaultOpenSSLContextFactory(KEYFILE,CERTFILE)
        reactor.listenSSL(PORT, server.Site(resource = wrapper),sslCF)
    else:
        reactor.listenTCP(PORT, server.Site(resource = wrapper))
    reactor.run()

joe=’blow’ ist die User/Passwort Kombination. Die InMemoryDatabase sollte natürlich nicht produktiv genutzt werden, wie der Name schon sagt. Dafür gibt es bspw. die FilePasswordDB. Irgendwo müssen noch die Variablen definiert werden:

PORT = 8888
SSL = True
KEYFILE = "key.pem"
CERTFILE = "cert.pem"

Das KEYFILE und CERTFILE muss dazu vorhanden sein. Bei PHP Magazine gibt es eine Anleitung, wie man sich für Tests die Zertifikate selbst ausstellen kann.

Wenn der Server dann läuft, kann man mit einem beliebigen XML-RPC Client darauf zugreifen. Hier als Beispiel der Python xmlrpcclient:

import xmlrpclib

PORT = 8888
SERVER= "localhost"
SSL = True
USER = "joe"
PASSWORD = "blow"

# generate URL
URL=USER+":"+PASSWORD+"@"+SERVER+":"+str(PORT)

if (SSL):
    #using no ssl
    server = xmlrpclib.ServerProxy("https://"+URL)
else:
    #using ssl
    server = xmlrpclib.ServerProxy("http://"+URL)

print server.test(2009,8)

Viel Spaß damit!

Leave a Reply