Skip to content

Instantly share code, notes, and snippets.

@brianv0
Created October 22, 2015 22:24
Show Gist options
  • Save brianv0/d7d0f0e3155537c09350 to your computer and use it in GitHub Desktop.
Save brianv0/d7d0f0e3155537c09350 to your computer and use it in GitHub Desktop.
HMAC SRS Auth
from auth import HMACAuthSRS
import requests
key_id = "..." #
secret_key = "..." #
url = "http://somewhere.slac.stanford.edu/SomeApplication"
auth = HMACAuthSRS(key_id, secret_key, url)
# See http://docs.python-requests.org/en/latest/user/quickstart/
resp = requests.get("http://somewhere.slac.stanford.edu/SomeApplication/someResource", auth=auth)
if resp.status_code == 200:
data = resp.json()
print data["key"]
resp = requests.post("http://somewhere.slac.stanford.edu/SomeApplication/someResource", data = {"key":"value"}, auth=auth)
if resp.status_code == 201:
print "Successful!"
import base64
from email.utils import formatdate
import hashlib
import hmac
from requests.auth import AuthBase
from urlparse import urlparse
__author__ = 'bvan'
class HMACAuth(AuthBase):
def __init__(self, key_id, secret_key, header_name, signature_format, url=None):
"""key_id must be base64"""
if url:
self.resource_base_url = url
self.key_id = str(key_id)
self.secret_key = base64.b64decode(str(secret_key))
self.header_name = header_name
self.sig_fmt = signature_format
def __call__(self, request):
# Create date header if it is not created yet.
if 'date' not in request.headers:
request.headers['date'] = formatdate(timeval=None, localtime=False, usegmt=True)
request.headers[self.header_name] = self.sig_fmt.format(self.key_id, self.get_signature(request))
return request
def get_signature(self, r):
canonical_string = self.get_canonical_string(r.url, r.headers, r.method)
h = hmac.new(self.secret_key, canonical_string, digestmod=hashlib.sha1)
return base64.encodestring(h.digest()).strip()
def get_canonical_string(self, url, headers, method):
parsedurl = urlparse(url)
d_headers = {}
for key in headers:
lk = key.lower()
d_headers[lk] = headers[key]
# hacky way of doing this...
if self.resource_base_url:
rpath = parsedurl.path.replace(urlparse(self.resource_base_url).path, "")
else:
rpath = "/" + "".join(parsedurl.path.split("/r/")[1:])
if parsedurl.params and len(parsedurl.params):
rpath = rpath + ";" + parsedurl.params
content_md5 = d_headers['content-md5'] if 'content-md5' in d_headers else ""
content_type = d_headers['content-type'] if 'content-type' in d_headers else ""
date = d_headers['date']
hash_buf = "%s\n%s\n%s\n%s\n%s\n" % (method, rpath, content_md5, content_type, date)
return hash_buf
# noinspection PyAbstractClass
class HMACAuthSRS(HMACAuth):
def __init__(self, key_id, secret_key, url=None):
super(HMACAuthSRS, self).__init__(key_id, secret_key, u"Authorization", u"SRS:{0}:{1}", url)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment