Skip to main content

Flask-HmacAuth

Build Status A module to simplify HMAC-style authentication for RESTful APIs in Flask, which also builds in a simple RBAC concept and anti-replay via a timestamp. For GET requests, the path section and all parameters are hashed. For POST requests, the request body is added as well. By default, the module expects authentication via an X-Auth-Signature header and ACCOUNT_ID and TIMESTAMP parameters (holding the obvious values) to be present in the query string or request body. TIMESTAMP can be in any format datetime.fromtimestamp() can parse. ACCOUNT_ID will be used to lookup a given account’s secret and roles via an AccountBroker. If auth fails, the application throws a 403 back to the client. All of that can be changed, however.

The concept of an AccountBroker is used to separate this module from any actual user/role management logic. 2 trivial AccountBroker implementations have been provided.

Example

Server

from flask import Flask
from flask.ext.hmacauth import hmac_auth, DictAccountBroker, HmacManager

app = Flask(__name__)
accountmgr = DictAccountBroker(
    accounts={
        "admin": {"secret": ";hi^897t7utf", "rights": ["create", "edit", "delete", "view"]},
        "editor": {"secret": "afstr5afewr", "rights": ["create", "edit", "view"]},
        "guest": {"secret": "ASDFjoiu%i", "rights": ["view"]}
    })
hmacmgr = HmacManager(accountmgr, app)
...
@app.route('/api/v1/create')
@hmac_auth("create")
def create_thing():
    ...

Client

import requests
import time

path_and_query = "/api/v1/create?TIMESTAMP="+str(int(time.time()))+"&ACCOUNT_ID=admin&foo=bar"
host = "https://example.com"
sig=hmac.new(";hi^897t7utf", msg=path_and_query).hexdigest()
req = requests.get(host+path_and_query, headers={'X-Auth-Signature': sig})

AccountBroker

An AccountBroker is an object that intermediates between the HMAC authentication and your user/account store. It does this by exposing the following methods:

  • get_secret(account_id) - returns a string secret given an account ID. If the account does not exist, returns None

  • has_rights(account_id, rights) - returns True if account_id has all of the rights in the list rights, otherwise returns False. Returns False if the account does not exist.

  • is_active(account_id) - returns True if account_id is active (for whatever definition you want to define for active), otherwise returns False.

Flask-Hmacauth ships with 2 trivial AccountBroker implementations, a Dict-based AccountBroker (DictAccountBroker) and a static AccountBroker (StaticAccountBroker).

DictAccountBroker

Takes a dict of format:

{
    "accountID": {
        secret: "blahblah",
        rights: ["right1", "right2", "right3", ...]
    }
    ...
}

it also exposes the add_accounts and del_accounts methods to modify accounts on the fly.

StaticAccountBroker

Essentially disables all of the user and role management, and sets a static key for use in HMAC. NOTE, if you use this class you need to pass StaticAccountBroker.GET_ACCOUNT to HmacManager as the account_id parameter OR supply a dummy value for ACCOUNT_ID in the query string

Write your own

A very common case for larger applications will be user management via a database. In that case, your AuthenticationBroker class just needs to perform the requisite SQL queries to satisfy the the methods above and you’re good to go.

HmacManager

This is the meat of the module. This object contains the is_authorized method, which actually does the HMAC verification and role checks.

In the simple case, you just need to pass this object’s constructor the flask application object and an AccountBroker object. In more complex cases, where you want to change defaults, you have the following options:

  • app - this is the Flask application container

  • account_broker - this is the ApplicationBroker object

  • account_id - this is a callable, which when fed a request object will return the request’s account ID. The default value for this is lambda x: x.values.get(‘ACCOUNT_ID’)

  • signature - this is a callable, which when fed a request object will return the request’s signature. The default value for this is GET_SIGNATURE = lambda x: x.headers.get(‘X-Auth-Signature’).

  • timestamp - this is a callable, which when fed a request object will return the request’s timestamp. The default value for this is lambda x: x.values.get(‘TIMESTAMP’)

  • valid_time - number of seconds that a signed request is valid (based on the signed timestamp). defaults to 5

  • digest - digest type, defaults to hashlib.sha1

Download files

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

Source Distribution

flask-hmacauth-0.2.tar.gz (5.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flask_hmacauth-0.2-py2.7.egg (8.7 kB view details)

Uploaded Egg

File details

Details for the file flask-hmacauth-0.2.tar.gz.

File metadata

  • Download URL: flask-hmacauth-0.2.tar.gz
  • Upload date:
  • Size: 5.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for flask-hmacauth-0.2.tar.gz
Algorithm Hash digest
SHA256 5b8d56b6b173a0ea686decd45ef32d751cb54e4e60ebc9a982ec170cdbc75994
MD5 1e988313aa91d3325bce7b5ac406338a
BLAKE2b-256 72cc5f4a022143235a926491e300b98858f4dd7fa3903d09ed520d369037a8b6

See more details on using hashes here.

File details

Details for the file flask_hmacauth-0.2-py2.7.egg.

File metadata

File hashes

Hashes for flask_hmacauth-0.2-py2.7.egg
Algorithm Hash digest
SHA256 d9ce0b9b07099a8b3883d7f4752c09bfc25a384a1b753d6cdf658a651042f65b
MD5 d338059f6bb3e9aab9079e5f97aa3183
BLAKE2b-256 85e93040811e8c872bc72106d42f5c9828badf68cc8b83e9b9a7ba771244cb1a

See more details on using hashes here.

Supported by

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