omab/django-social-auth — Issue #204: Race Condition results in "Incorrect authentication service"
Author: stephenmcd
Created: 2011-12-23 00:56:18+00:00
State: open

I searched previous issues for "Incorrect authentication service" and it seems like there have been many, as there are a variety of problems that can occur resulting in the backend not being found. Many of the issues are closed as the resulting problems were misconfigurations with backends, but I believe I've come across a fundamental problem that can occur with how backends are discovered.

Note: It *won't* be a problem when using Django's development server as it's a single process/thread, but when running under a multi process/thread environment as most production environments will use, a race condition can sometimes occur.

The fundamental problem is that social_auth.backends.BACKENDS is populated at import time, and that may occur prior to all backend classes having actually been defined. Particularly, backends usually *require* importing base classes from social_auth.backends that they can subclass, prior to them having been defined. The BACKENDS population code then runs, and the backend classes aren't picked up as they haven't been defined yet.

Like I said you won't be able to reproduce this using Django's development server, but if you run a project using gunicorn you will eventually come across this issue after a number of restarts of gunicorn. Sometimes it will work, other times it won't. The behaviour basically sticks to each startup of a project, since the code only runs once when first imported.

A workaround for me has been to explicitly add my backend to social_auth.backends.BACKENDS in my urlconf and this resolves the issue.

As a more permanent solution, I would recommend throwing out the whole approach of walking the filesystem from SOCIAL_AUTH_IMPORT_SOURCES, and just have SOCIAL_AUTH_ENABLED_BACKENDS defined as Python dotted paths (in the same way Django defines INSTALLED_APPS, MIDDLEWARE_CLASSES etc) that are imported inside get_backend, making get_backends, BACKENDS, and SOCIAL_AUTH_IMPORT_SOURCES no longer required. If this sounds like a good approach please let me know, I'd be happy to submit a pull request to fix it, but I thought I'd just gauge the direction you'd like to take first.

Finally, thanks for the awesome app - it really is an amazing piece of work that obviously a ton of effort has been put into, and one of my always-go-to solutions for the problem it solves.