The djoauth2 Code

access_token Module

class djoauth2.access_token.AccessTokenAuthenticator(required_scope_names=())[source]

Allows easy authentication checking and error response creation.

See the validate() method’s docstring for a usage example. We strongly recommend that you use the djoauth2.decorators.oauth_scope() decorator to protect your API endpoints instead of manually instatiating this object.

make_error_response(validation_error, expose_errors)[source]

Return an appropriate HttpResponse on authentication failure.

In case of an error, the specification only details the inclusion of the WWW-Authenticate header. Additionally, when allowed by the specification, we respond with error details formatted in JSON in the body of the response. For more information, read the specification: http://tools.ietf.org/html/rfc6750#section-3.1 .

Parameters:
  • validation_error – A djoauth2.access_token.AuthenticationError raised by the validate() method.
  • expose_errors – A boolean describing whether or not to expose error information in the error response, as described by the section of the specification linked to above.
Return type:

a Django HttpResponse.

validate(request)[source]

Checks a request for proper authentication details.

Returns a tuple of (access_token, error_response_arguments), which are designed to be passed to the make_error_response() method.

For example, to restrict access to a given endpoint:

def foo_bar_resource(request, *args, **kwargs):
  authenticator = AccessTokenAuthenticator(
      required_scope_names=('foo', 'bar'))

  access_token, error_args = authenticator.validate(request)
  if not access_token:
    return authenticator.make_error_response(*error_args)

  # ... can now return use access_token
Return type:When the request validates successfully, returns a a tuple of (djoauth2.models.AccessToken, None). If the request fails to validate, returns a tuple of (None, error_details_tuple). The error_details_tuple is a tuple of arguments to use to call the make_error_response() method.
class djoauth2.access_token.AuthenticationError[source]

Base class for errors related to API request authentication.

For more details, refer to the Bearer Token specification:

authorization Module

class djoauth2.authorization.AuthorizationCodeGenerator(missing_redirect_uri)[source]

Allows easy authorization request validation, code generation, and redirection creation.

Use as part of your authorization page endpoint like so:

def authorization(request):
  auth_code_generator = AuthorizationCodeGenerator(
      '/oauth2/missing_redirect_uri/')
  try:
    auth_code_generator.validate(request)
  except AuthorizationError as e:
    return auth_code_generator.make_error_redirect()

  if request.method == 'GET':
    # Show a page for the user to see the scope request. Include a form
    # for the user to authorize or reject the request. Make sure to
    # include all of the # original authorization request's parameters
    # with the form so that they # can be accessed when the user submits
    # the form.
    original_request_parameters = (
        auth_code_generator.get_request_uri_parameters())
    # See the template example below.
    template_render_context = {
        'form': Form(),
        'client': auth_code_generator.client,
        'scopes': auth_code_generator.valid_scope_objects,
        # Assumes that this endpoint is connected to
        # the '/oauth/authorization/' URL.
        'form_action': ('/oauth2/authorization/?' +
                        original_request_parameters),
      }
    return render(request,
                  'oauth2server/authorization_page.html',
                  template_render_context)
  elif request.method == 'POST':
    # Check the form the user submits (see the template below.)
    if request.POST.get('user_action') == 'Accept':
      return auth_code_generator.make_success_redirect()
    else:
      return auth_code_generator.make_error_redirect()

An example template ('oauth2server/authorization_page.html' from the above example) should look something like this:

<p>{{client.name}} is requesting access to the following scopes:</p>

<ul>
  {% for scope in scopes %}
  <li> <b>{{scope.name}}</b>: {{scope.description}} </li>
  {% endfor %}
</ul>


<form action="{{form_action}}" method="POST">
  {% csrf_token %}
  <div style="display: none;"> {{form}} </div>
  <input type="submit" name="user_action" value="Decline"/>
  <input type="submit" name="user_action" value="Accept"/>
</form>

We strongly recommend that you avoid instantiating this class. Instead, prefer the djoauth2.authorization.make_authorization_endpoint()

get_request_uri_parameters(as_dict=False)[source]

Return the URI parameters from a request passed to the ‘validate’ method

The query parameters returned by this method MUST be included in the action="" URI of the authorization form presented to the user. This carries the original authorization request parameters across the request to show the form to the request that submits the form.

Parameters:as_dict – default False. If True, returns the parameters as a dictionary. If False, returns the parameters as a URI-encoded string.
make_error_redirect(authorization_error=None)[source]

Return a Django HttpResponseRedirect describing the request failure.

If the validate() method raises an error, the authorization endpoint should return the result of calling this method like so:

>>> auth_code_generator = (
>>>     AuthorizationCodeGenerator('/oauth2/missing_redirect_uri/'))
>>> try:
>>>   auth_code_generator.validate(request)
>>> except AuthorizationError as authorization_error:
>>>   return auth_code_generator.make_error_redirect(authorization_error)

If there is no known Client redirect_uri (because it is malformed, or the Client is invalid, or if the supplied redirect_uri does not match the regsitered value, or some other request failure) then the response will redirect to the missing_redirect_uri passed to the __init__() method.

Also used to signify user denial; call this method without passing in the optional authorization_error argument to return a generic AccessDenied message.

>>> if not user_accepted_request:
>>>   return auth_code_generator.make_error_redirect()
make_success_redirect()[source]

Return a Django HttpResponseRedirect describing the request success.

The custom authorization endpoint should return the result of this method when the user grants the Client’s authorization request. The request is assumed to have successfully been vetted by the validate() method.

validate(request)[source]

Check that a Client’s authorization request is valid.

If the request is invalid or malformed in any way, raises the appropriate exception. Read the relevant section of the specification for descriptions of each type of error.

Raises:a AuthorizationError if the request is invalid.
djoauth2.authorization.make_authorization_endpoint(missing_redirect_uri, authorization_endpoint_uri, authorization_template_name)[source]

Returns a endpoint that handles OAuth authorization requests.

The template described by authorization_template_name is rendered with a Django RequestContext with the following variables:

  • form: a Django Form that may hold data internal to the djoauth2 application.
  • client: The djoauth2.models.Client requesting access to the user’s scopes.
  • scopes: A list of djoauth2.models.Scope, one for each of the scopes requested by the client.
  • form_action: The URI to which the form should be submitted – use this value in the action="" attribute on a <form> element.
Parameters:
  • missing_redirect_uri – a string, the URI to which to redirect the user when the request is made by a client without a valid redirect URI.
  • authorization_endpoint_uri – a string, the URI of this endpoint. Used by the authorization form so that the form is submitted to this same endpoint.
  • authorization_template_name – a string, the name of the template to render when handling authorization requests.
Return type:

A view function endpoint.

class djoauth2.authorization.AuthorizationError[source]

Base class for authorization-related errors.

Read the specification: http://tools.ietf.org/html/rfc6749#section-4.1.2.1 .

conf Module

class djoauth2.conf.DJOAuth2Conf(**kwargs)[source]

Default OAuth-related implementation settings.

Implementation-specific settings. Each of the settings can be overridden in your own setup.py with a DJOAUTH2_ prefix like so:

settings.DJOAUTH2_SETTING_NAME = <Value>

That said, in order to maintain the highest level of security and to avoid breaking the specification’s rules or recommendations, we strongly recommend that you do not change these values Doing so can break compliance with the OAuth specification, and/or introduce large security flaws into the authentication process. Please read through the Security Considerations and convince yourself that you really know what you’re doing before changing any of these values.

ACCESS_TOKENS_REFRESHABLE = True
ACCESS_TOKEN_LENGTH = 30
ACCESS_TOKEN_LIFETIME = 3600
AUTHORIZATION_CODE_LENGTH = 30
AUTHORIZATION_CODE_LIFETIME = 600
CLIENT_KEY_LENGTH = 30
CLIENT_SECRET_LENGTH = 30
class Meta[source]
prefix = 'djoauth2'
DJOAuth2Conf.REALM = ''

This value is used in the construction of the WWW-Authenticate header in responses to incorrectly-authenticated API requests. The specification does not specify any particular realm, and I am unable to get a good idea of how the value might be used from anywhere else on the internet. If you have a good understanding of HTTP Authorization Realms, please submit a pull request!

DJOAuth2Conf.REFRESH_TOKEN_LENGTH = 30
DJOAuth2Conf.REQUIRE_STATE = True

The “state” parameter is used during requests for djoauth2.models.AuthorizationCode objects, because those requests redirect the user’s browser back to the Client’s registered endpoint. From the specification ( http://tools.ietf.org/html/rfc6749#section-10.12 ):

The client MUST implement CSRF protection for its redirection URI. This is typically accomplished by requiring any request sent to the redirection URI endpoint to include a value that binds the request to the user-agent’s authenticated state (e.g., a hash of the session cookie used to authenticate the user-agent). The client SHOULD utilize the “state” request parameter to deliver this value to the authorization server when making an authorization request.

If you would like to ignore the specification’s recommendations, change this value to False. Sometimes this is useful during local development and testing, but this value should never be set to False in a production environment.

DJOAuth2Conf.SSL_ONLY = True

From http://tools.ietf.org/html/rfc6749#section-3.1.2.1 :

The redirection endpoint SHOULD require the use of TLS as described in Section 1.6 when the requested response type is “code” or “token”, or when the redirection request will result in the transmission of sensitive credentials over an open network. This specification does not mandate the use of TLS because at the time of this writing, requiring clients to deploy TLS is a significant hurdle for many client developers. If TLS is not available, the authorization server SHOULD warn the resource owner about the insecure endpoint prior to redirection (e.g., display a message during the authorization request).

Lack of transport-layer security can have a severe impact on the security of the client and the protected resources it is authorized to access. The use of transport-layer security is particularly critical when the authorization process is used as a form of delegated end-user authentication by the client (e.g., third-party sign-in service).

If you’d like to develop your OAuth endpoints locally without having to set up an SSL server, change this value to False. We do not recommend changing this value in a production environment – the security of your users will be greatly compromised.

decorators Module

djoauth2.decorators.oauth_scope(*scope_names)[source]

Return a decorator that restricts requests to those authorized with a certain scope or scopes.

For example, to restrict access to a given endpoint like this:

@require_login
def secret_attribute_endpoint(request, *args, **kwargs):
  user = request.user
  return HttpResponse(json.dumps({
      'super_secret_attribute' : user.super_secret_attribute
    })

...just add the decorator and an additional argument to the function’s signature:

@oauth_scope('foo', 'bar')
def secret_attribute_endpoint(access_token, request, *args, **kwargs):
  # Because of the decorator, the function is guaranteed to only be run
  # if the request includes proper access to the 'foo' and 'bar'
  # scopes.
  user = access_token.user
  return HttpResponse(json.dumps({
      'super_secret_attribute' : user.super_secret_attribute
    })

The first argument to the wrapped endpoint will now be an djoauth2.models.AccessToken object. The second argument will be the original Django HttpRequest, and all other parameters included in the requests (due to URL-matching or any other method) will follow.

We strongly recommend that you use this decorator to protect your API endpoints instead of manually instantiating a djoauth2.access_token.AccessTokenAuthenticator object.

errors Module

exception djoauth2.errors.DJOAuthError[source]

Base class for all OAuth-related errors.

error_name = 'invalid_request'
status_code = 400
djoauth2.errors.get_error_details(error)[source]

Return details about an OAuth error.

Returns a mapping with two keys, 'error' and 'error_description', that are used in all error responses described by the OAuth 2.0 specification. Read more at:

models Module

class djoauth2.models.AccessToken(*args, **kwargs)[source]

AccessToken(id, client_id, date_created, lifetime, invalidated, authorization_code_id, refreshable, refresh_token, user_id, value)

class djoauth2.models.AuthorizationCode(*args, **kwargs)[source]

AuthorizationCode(id, client_id, user_id, date_created, lifetime, invalidated, redirect_uri, value)

class djoauth2.models.Client(*args, **kwargs)[source]

Client(id, user_id, name, description, image_url, redirect_uri, key, secret)

class djoauth2.models.Scope(*args, **kwargs)[source]

Scope(id, name, description)

views Module

djoauth2.views.access_token_endpoint(*args, **kwargs)[source]

Generates djoauth2.models.AccessTokens if provided with sufficient authorization.

This endpoint only supports two grant types:

For further documentation, read http://tools.ietf.org/html/rfc6749#section-3.2