A user has requested that RPC4Django support HTTP access control. This is the new preferred method where newer browsers are allowed to make cross domain AJAX requests (with specific constraints) without having to resort to hacks and workarounds like dynamic script tags. I also want to work on JSON class hinting, which is not currently supported. I’m shooting to get this going in the next week before I leave for a Mexican vacation. Swine flu has made the Mexican resorts very reasonable.
Weird Issue on Chrome
In addition, I have noticed that the authenticated demo site does not work in Google Chrome. Is anyone else experiencing this? Any idea why? There’s no problem with Chrome on the demo site not running ssl.
Hi,
Thanks for this wonderful application!
I’m having an hard time testing my services, particularly: I cannot make authentication work (user admin password admin can log in the control panel).
Also, I should be able to access the request object (or at least the authenticated User informations) from inside the method, do you know any way to do it?.
Settings:
MIDDLEWARE_CLASSES = (
‘django.middleware.common.CommonMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
# Required for RPC4Django authenticated method calls
# Requires Django 1.1+
‘django.contrib.auth.middleware.RemoteUserMiddleware’,
‘django.middleware.locale.LocaleMiddleware’,
‘middleware.SiteDetectionMiddleware’,
)
AUTHENTICATION_BACKENDS = (
‘django.contrib.auth.backends.RemoteUserBackend’,
# if the following line is commented, I cannot log in the control panel!!!
‘django.contrib.auth.backends.ModelBackend’,
)
Test:
from xmlrpclib import ServerProxy
s = ServerProxy(‘http://admin:admin@127.0.0.1:8000/RPC2’)
r = s.risorse.add_category(‘test_cat’, ‘test_desc’)
xmlrpclib.ProtocolError:
I’m glad you’re using it!
What message is the protocol error giving you? A “401 Unauthorized” is a protocol error and RPC4Django will return that if you don’t have access to call the appropriate method. I ask this because you have enabled the remote user middleware and you mentioned that you still needed admin/admin to login to the control panel. With the remote user middleware working properly, you should not need to login to the demo site because you would already be authenticated with Apache. If you aren’t using Apache authentication, there’s no need to send the authentication with the XMLRPC request.
I think with a little more information about your setup, we can get to the bottom of this.
Thank you for answering,
I’m using the manage.py testing server, I solved the issue writing a middleware that checks HTTP_AUTHORIZATION
class HttpAuthMiddleware:
def process_request(self, request):
auth_basic = request.META.get(‘HTTP_AUTHORIZATION’)
if auth_basic:
import base64
try:
username , dummy, password = base64.decodestring(auth_basic[6:]).partition(‘:’)
user = User.objects.get(username=username)
if user.check_password(password):
request.user = user
except User.DoesNotExist:
return None
I’m confused about how RemoteUserMiddleware works, it just checks for a previous session ? It seems like it never checks for a password…
I’m trying to have this setup:
* users can normally login through admin site with cookie based auth (default Django behavior)
* machine-2-machine webservice calls should use HTTP Basic sending credentials from standard libraries like http://username:password@example.com
I’m now successfully doctesting rpc4django with something like:
>>> from django.core.management import call_command
>>> # install fixture
>>> call_command(‘loaddata’, ‘auth_sites.json’)
Installing json fixture ‘auth_sites’ from…
Installed…
>>> from django.test.client import Client
>>> c = Client()
>>> from xmlrpclib import *
>>> r = c.post(‘/RPC2’, dumps(tuple([ “cat_test”, “cat_desc”]), “risorse.add_category”) , content_type = ‘text/xml’)
… DEBUG Method “risorse.add_category” is protected by permission “add_category”
… INFO User “AnonymousUser” is NOT authorized
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username=’admin’)
>>> u
>>> c.login(username=’admin’, password=’admin’)
True
>>> r = c.post(‘/RPC2’, dumps(tuple([ “cat_test1”, “cat_desc1”]), “risorse.add_category”) , content_type = ‘text/xml’)
… DEBUG Method “risorse.add_category” is protected by permission “add_category”
… DEBUG User “admin” is authorized
One more question: I had to change rpcdispatcher.py to allow_none:
self.xmlrpcdispatcher = SimpleXMLRPCDispatcher(allow_none=True,
encoding=None)
Why did you set it up to not allow none? Is there a particular reason ?
You really did a great job with rpc4django !!
I would be happy to donate you a beer or two via paypal.
The RemoteUserMiddleware doesn’t actually check the password because it assumes that your web server has already done that for you. With Apache, you would probably be using something like Django’s mod_python auth handler or the soon to be integrated (hopefully) mod_wsgi auth handler. This is pretty common for an intranet deployment, but an internet deployment might want to use the cookie/session based approach that you implemented with your custom middleware.
As for
allow_none
, there is no particular reason. In fact, I think it should be allowed or at least optional. It may require some testing because I believe they added that parameter to SimpleXMLRPCDispatcher in Python 2.5. I’ll add this to the TODO list.I’m glad to see you’re using RPC4Django. Normally, I’d be glad to take a beer via Paypal, but I have 5 gallons of bourbon vanilla porter bottle conditioning right now. It should be ready to drink in about a week and a half. Instead, if you feel like donating, please take a look at my wish list.