secure access to xmlrpc, soap (access from ip-ranges, login, ssl) - a feasible approach?
Hi I would like to write a server, that delivers the same services over xmlrpc or soap. It is no problem to design this. The problem arises when it comes to authentification. What I want: - Deliver services in xmlrpc or soap - Deliver services only to people in well defined ip-ranges (192.168.1.*,...) - Deliver services only to logged in users (except for login requests which should always pass!) - User don't have to log in each time they do a request! (overhead would be deadly) - Deliver services encrypted (ssl) if desired What I have: - I have a server that delivers services over xmlrpc or soap - I have a class that keeps track for users that have logged in/expired/available. - I have a class that can test, whether the request comes from a valid ip. The problem(s): - I know that twisted has "cred" library to authentificate people. I don't see how this is usable with a stateless protocol like xmlrpc or soap. As far as I understood the "cred"-library does not apply to xmlrpc or soap. If it does, than a simple exmaple would be very nice. To me it seems, that the best point to enforce "authentification" and "logged sessions" is to override render-method of --> twisted.web.xmlrpc.XMLRPC --> twisted.soap.SOAPPublisher from twisted.web.xmlrpc import XMLRPC import xmlrpclib import bsw_config class XMLRPC_WITH_AUTH(XMLRPC): def __init__(self): XMLRPC.__init__(self) def render(self, request): """Overriding this let me introduce authentification.""" # <Modification> # --> verify whether the ip is in the allowed range --> # I do it here, before any further handling is done! # verify --> request.client.host is allowed # </Modification> request.content.seek(0, 0) args, functionPath = xmlrpclib.loads(request.content.read()) # <Modification> # Always let login request pass! (xxx Multicall?) if not functionPath == u"do_login": # verify user logged in already based on IP (port always changes - # because xmlrpc is stateless) # what other possibilty do I have for a unique id? if not verify_user_is_logged_in(request.client.host): self._cbRender(Fault(xxx, xxx) , request) return server.NOT_DONE_YET # </Modification> try: function = self._getFunction(functionPath) except Fault, f: self._cbRender(f, request) else: request.setHeader("content-type", "text/xml") defer.maybeDeferred(function, *args).addErrback( self._ebRender ).addCallback( self._cbRender, request ) return server.NOT_DONE_YET The two <modification></modification> show my intended interventions. Is this a feasible approach? The only unique id I have from the client is his IP - the socket/port, as I said, changes with each request (stateless nature of xmlrpc/soap). This poses a security risk, because clients served from the same proxy/router/firewall have the same IP... which forces me to add a unique token to each request (please not). Do you know another unique item of each request, that identifies the client further? To further secure the transport, I would like to be able to transport the data over ssl. Is this as easy as: reactor.listenSSL(XMLRPC_PORT, server.Site(XmlrpcPublisher()), some_cert) reactor.listenSSL(SOAP_PORT, server.Site(SoapPublisher()), some_cert) Thanks for all your answers in advance, Greetins, Marco
participants (1)
-
Marco Aschwanden