Jump to >

Adding OAuth2 Support

Overview

The Web API utilities provided by Djblets can be augmented to add support for authentication via OAuth2. In order to do this, there are a few steps:

Additional Requirements

OAuth2 support requires the django-oauth-toolkit module to be installed. This module has only been tested with version 0.9.0.

settings.py

The following settings need to be updated in settings.py to take advantage of OAuth2 support.

INSTALLED_APPS:
Add 'oauth2_provider' to this list.
WEB_API_AUTH_BACKENDS:

Add ''djblets.webapi.auth.backends.oauth2_tokens.OAuth2TokenAuthBackend' to this list.

settings.py
WEB_API_AUTH_BACKENDS = (
    'djblets.webapi.auth.backends.basic.WebAPIBasicAuthBackend',
    'djblets.webapi.auth.backends.oauth2_tokens.OAuth2TokenAuthBackend',
)
AUTHENTICATION_BACKENDS:

Create an authentication backend using OAuth2TokenBackendMixin and add it to this setting:

my_app/auth_backends.py
from djblets.webapi.auth.backends.oauth2_tokens import OAuth2TokenBackendMixin
from django.contrib.auth.backends import ModelBackend

class EnabledOAuth2TokenBackend(OAuth2TokenBackendMixin, ModelBackend):
    """An OAuth2 token auth backend using a custom Application model."""

    def verify_request(self, request, token, user):
        return token.application.some_custom_property
settings.py
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    # ...
    'myapp.auth_backends.EnabledOAuth2TokenBackend',
)
WEB_API_ROOT_RESOURCE:

Define this to be the full import path of your root resource.

settings.py
WEB_API_ROOT_RESOURCE = 'myapp.webapi.resources.root.root_resource'
WEB_API_SCOPE_DICT_CLASS:

This setting determines what class defines the OAuth2 scopes for your web API. By default, each resource will require scope_name:method where scope_name is defined by ResourceOAuth2TokenMixin.scope_name and method is one of read (for HTTP GET, HEAD, and OPTIONS), write (for HTTP PUT and POST), or destroy (for HTTP DELETE).

Djblets provides two possible scope dictionary classes for your web API:

djblets.webapi.oauth2_scopes.ExtensionEnabledWebAPIScopeDictionary:
For apps that use the djblets extensions framework.
djblets.webapi.oauth2_scopes.WebAPIScopeDictionary:
For apps that do not use the djblets extensions framework.
settings.py
# If using extensions:
WEB_API_SCOPE_DICT_CLASS = \
    'djblets.webapi.oauth2_scopes.ExtensionEnabledWebAPIScopeDictionary'

# Otherwise:
WEB_API_SCOPE_DICT_CLASS = \
    'djblets.webapi.oauth2_scopes.WebAPIScopeDictionary'
OAUTH_PROVIDER:

This setting must, at a minimum, define the DEFAULT_SCOPES and SCOPES keys. The following example presumes that your root resource is named 'root' and you are using one of the provided scope dictionaries.

The SCOPES key should be an empty dictionary. It will be replaced at runtime with the proper dictionary.

settings.py
OAUTH2_PROVIDER = {
     'DEFAULT_SCOPES': 'root:read',
     'SCOPES': {},
}

Resource Classes

Resources should all inherit from a base class that includes the provided mixin for OAuth2 support.

from djblets.webapi.resources.base import WebAPIResource as \
    BaseWebAPIResource
from djblets.webapi.resources.mixins.oauth2_tokens import \
    ResourceOAuth2TokenMixin


class WebAPIResource(ResourceOAuth2TokenMixin, BaseWebAPIResource):
    """The base resource class.

    All resources should inherit from this.
    """

If you wish to disable access to a resource when using an OAuth2 token, you may set the oauth2_token_access_allowed attribute to False.

Enabling Web API OAuth Scopes

Finally, to enable the web API scope dictionary, you must run enable_webapi_scopes() at runtime. This should be run when your app is starting.

If you are on Django 1.7+, you should call this function in your AppConfig.ready method:

my_app/apps.py
from django.apps import AppConfig


class WebApiAppConfig(AppConfig):
    def ready(self):
        """Enable the WebAPI scopes dictionary."""
        from djblets.webapi.oauth2_scopes import enable_webapi_scopes

        enable_oauth2_scopes()

Otherwise if you are on Django 1.6, you may call it in your root urls.py:

urls.py
from djblets.webapi.oauth2_scopes import enable_webapi_scopes


urlpatterns = [
    # ...
]

enable_oauth2_scopes()