Skip to main content

HTTP Signature support for Django REST framework

Project description

drf-httpsig

Easy HTTP Signature authentication support for the Django REST framework.

Overview

The HTTP Signature scheme provides a way to achieve origin authentication and message integrity for HTTP messages. Similar to Amazon’s HTTP Signature scheme, used by many of its services. The HTTP Signature specification is currently an IETF draft.

Requirements

  • Python 2.7, 3.3+ (currently tested up to 3.4)

  • httpsig

Installation

This module uses setuptools and is hosted on PyPi so installation is as easy as:

pip install drf-httpsig

This should also install the httpsig module which houses all the magic; this module is pure DRF glue (as it should be).

You can also run setup.py from inside a clone of the repository:

python setup.py install

Note that if you do so, modules with a version requirement may attempt to re-install the module as versioneer may report a different version, especially if your clone of the repo has any uncommitted/untagged changes.

Running the Tests

To run the tests for the module, use the following command on the repository root directory:

python setup.py test

Note that testing depends on django-nose, which will be installed before testing. You may also run the tests with tox using the included tox.ini file which has the benefit of keeping all testing dependances in a venv automatically.:

tox -e py27,py32,…

Usage

To actually authenticate HTTP requests with this module, you need to extend the SignatureAuthentication class, as follows:

# my_api/auth.py

from drf_httpsig.authentication import SignatureAuthentication

class MyAPISignatureAuthentication(SignatureAuthentication):
    # The HTTP header used to pass the consumer key ID.

    # A method to fetch (User instance, user_secret_string) from the
    # consumer key ID, or None in case it is not found. Algorithm
    # will be what the client has sent, in the case that both RSA
    # and HMAC are supported at your site (and also for expansion).
    def fetch_user_data(self, key_id, algorithm="hmac-sha256"):
        # ...
        # example implementation:
        try:
            user = User.objects.get(keyId=key_id, algo=algorithm)
            return (user, user.secret)
        except User.DoesNotExist:
            return (None, None)
  1. Configure DRF to use your authentication class; e.g.:

# my_project/settings.py

# ...
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
       'my_api.auth.MyAPISignatureAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}
# The above will force HTTP signature for all requests.
# ...

Support

Please file any issues in the issue tracker. You are also welcome to contribute features and fixes via pull requests.

Example Usage and Session w/cURL

Assuming the setup detailed above, a project running on localhost:8000 could be probed with cURL as follows:

# Pre-calculate this first bit.
~$ SSS=Base64(Hmac(SECRET, "Date: Mon, 17 Feb 2014 06:11:05 GMT", SHA256))
~$ curl -v -H 'Date: "Mon, 17 Feb 2014 06:11:05 GMT"' -H 'Authorization: Signature keyId="my-key",algorithm="hmac-sha256",headers="date",signature="SSS"'

And, with much less pain, using the modules requests and httpsig:

import requests
from httpsig.requests_auth import HTTPSignatureAuth

KEY_ID = 'su-key'
SECRET = 'my secret string'

signature_headers = ['(request-target)', 'accept', 'date', 'host']
headers = {
  'Host': 'localhost:8000',
  'Accept': 'application/json',
  'Date': "Mon, 17 Feb 2014 06:11:05 GMT"
}

auth = HTTPSignatureAuth(key_id=KEY_ID, secret=SECRET,
                       algorithm='hmac-sha256',
                       headers=signature_headers)
req = requests.get('http://localhost:8000/resource/',
                 auth=auth, headers=headers)
print(req.content)

drf-httpsig Changes

v1.2.0 (2018-Mar-28)

  • Updated to support and require httpsig 1.x.

  • Switched to pytest over nose

v1.1.0 (2015-Feb-11)

  • Updated to support and require httpsig 1.1.

  • Updated requirements to simply Django<1.7 and DRF<3.0. Last version for those, I suspect.

v1.0.2 (2014-Jul-24)

  • Updated authentication return value to set request.auth to the key_id used.

v1.0.1 (2014-Jul-03)

  • Added/verified Python 3 support and tests (3.2+).

  • Added support for sending a DRF authorization challenge if we’re the primary authenticator.

  • Switched to using the httpsig HeaderVerifier instead of doing it ourselves. Lots of code got deleted there.

  • Changed fetch_user_data to also receive the algorithm the keyID is for.

  • Updated README.

  • Removed models.py – the client should handle that part entirely.

v1.0b2/1.0.0 (2014-Jul-01)

  • Added versioneer.

  • Updated requirements to use latest httpsig.

  • Added “setup.py test” and tox support.

  • Fixed a unit test.

v1.0b1 (2014-Jun-27)

  • Renamed to drf-httpsig because I don’t hate my hands.

  • Updated requirements versions to be more sane.

  • Switched to a different branch for http_signature.

  • Removed API_KEY_HEADER in favor of the keyId, per spec.

  • Cleaned up the repo a bit.

  • Cleaned up the code a bit.

djangorestframework-httpsignature (previous)

v0.1.5, 20140613 – Document installation issue

  • Document workaround on installation problems.

v0.1.4, 20140613 – Improve installation

  • Make requirements file comply with docs.

  • Decide on http_signature commit.

v0.1.3, 20140220 – Upload to PyPI

  • Prepare docs to upload package to PyPI

v0.1.2, 20140219 – Package data and clean up

  • Updated package classifiers

  • Cleaned up unused code in authentication.py

v0.1.1, 20140217 – Documentation and clean up

  • The package can be installed.

  • Continuous integration via Travis.

  • Unit tests for the authentication code.

  • General docuementation in the README file.

v0.1.0, 20140217 – Initial release

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drf-httpsig-1.2.0.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

drf_httpsig-1.2.0-py2.py3-none-any.whl (11.5 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file drf-httpsig-1.2.0.tar.gz.

File metadata

  • Download URL: drf-httpsig-1.2.0.tar.gz
  • Upload date:
  • Size: 9.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for drf-httpsig-1.2.0.tar.gz
Algorithm Hash digest
SHA256 4a0378679f35ce94cf32359dcc34e4d6894784f549f62e02584068ae6fa74f2f
MD5 1168d2eece51bc849076a7085da400a3
BLAKE2b-256 685564fa1f8a1e78d38692f4566bce217a2e263c520e8d5e8758f424f61541c8

See more details on using hashes here.

File details

Details for the file drf_httpsig-1.2.0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for drf_httpsig-1.2.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 0ae0920adf81148fcd88799a7043de3117511a0960024058c316986918fc104e
MD5 cd99a81cde2a2e7f49e93e798dc77355
BLAKE2b-256 91e8da39da30c2117d4e9e0daace8f3d93c690f60dcb1b1ce5384011dc515479

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page