Provides HTTP Signature support for Django REST framework. The HTTP Signature package 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.
Installing the package via the repository:
pip install djangorestframework-httpsignature
Older version of pip
don't support the Wheel format (which is how httpsig
is distributed). The problem manifests when installing the requirements, pip
will complain that it cannot find a httpsig
. In such cases, pip
needs to be upgraded:
pip install --upgrade pip
Another possible problem: while installing via python setup.py install
you may encounter:
No local packages or download links found for httpsig error: Could not find suitable distribution for Requirement.parse('httpsig')
If that is the case, use pip install httpsig
to install the httpsig
package and retry python setup.py install
.
To run the tests for the packages, use the following command on the repository root directory:
python manage.py test
To authenticate HTTP requests via HTTP signature, you need to:
Install this package in your Django project, as instructed in Installation.
Add
rest_framework_httpsignature
to yoursettings.py
INSTALLED_APPS.In your app code, extend the
SignatureAuthentication
class, as follows:# my_api/auth.py from rest_framework_httpsignature.authentication import SignatureAuthentication class MyAPISignatureAuthentication(SignatureAuthentication): # The HTTP header used to pass the consumer key ID. # Defaults to 'X-Api-Key'. API_KEY_HEADER = 'X-Api-Key' # A method to fetch (User instance, user_secret_string) from the # consumer key ID, or None in case it is not found. def fetch_user_data(self, api_key): # ... # example implementation: try: user = User.objects.get(api_key=api_key) return (user, user.secret) except User.DoesNotExist: return None
Configure Django REST framework to use you 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. # ...
You can also use another algorithm that is provided by httpsig package:
class MyAPISignatureAuthentication(SignatureAuthentication): API_KEY_HEADER = 'X-Api-Key' ALGORITHM = 'rsa-256' def fetch_user_data(self, api_key): try: user = User.objects.get(api_key=api_key) fpath = user.private_key with open(fpath, 'rb') as fobj: secret = fobj.read() return (user, secret) except User.DoesNotExist: return (None, None)
Currently supported throught httpsig
are: rsa-sha1
, rsa-sha256
, rsa-sha512
, hmac-sha1
, hmac-sha256
, hmac-sha512
- The
REQUIREMENTS.txt
file is fairly strict. It is very possible that previous versions of Django and Django REST framework are supported. - Since HTTP Signature uses a HTTP header for the request date and time, the authentication class could deal with request expiry.
Assuming the setup detailed in Usage, a project running on localhost:8000
could be probed with cURL as follows:
~$ 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 for a much less painful example, check out the httpsig package documentation to use requests
and httpsig
.