Authentication
All requests must be signed by the client.
Authentication Scheme
Sample Request:
GET /rest/directory/uin/000000000/json/ HTTP/1.1
Date: Tue, 04 May 2010 20:46:36 GMT
Authorization: TAM faa36ed8ef1a:4iRRBxwPuKD71JYYn7192Zuopkr3mPQ/HcQAfbSM2mQ=
Required Headers
Each request made by your client must provide, at a minimum, the Date and Authorization headers.
Date Header
The Date header should be provided in GMT, using a valid HTTP date format. The date in your request will be used to verify that the request is current. If you cannot set the date header for your request, you should instead set the x-tam-date
header using the same format:
GET /rest/directory/uin/000000000/json/ HTTP/1.1
x-tam-date: Tue, 04 May 2010 20:46:36 GMT
Authorization: TAM faa36ed8ef1a:4iRRBxwPuKD71JYYn7192Zuopkr3mPQ/HcQAfbSM2mQ=
Authorization Header
The Authorization header will have the following form:
Authorization: TAM identifier:signature
The identifier is specific to your client. The signature is a HMAC-SHA256 of an authentication string made up of the request URI, the date, and your client’s identifier.
The following pseudo-code illustrates how to build the signature:
Authorization = "TAM" + " " + identifier + ":" + signature;
signature = Base64( HMAC-SHA256( UTF-8-Encoding-Of( shared_secret, authentication_string ) ) );
authentication_string = request_uri + "\n" +
date + "\n" +
identifier;
The date should be exactly what is provided in the Date header. The request URI is the path of the endpoint.
Sample Code (Python)
import base64
import hmac
import hashlib
import requests
from datetime import datetime, tzinfo, timedelta
class GMT(tzinfo):
def dst(self, dt):
d = datetime(dt.year, 4, 1)
self.dston = d - timedelta(days=d.weekday() + 1)
d = datetime(dt.year, 11, 1)
self.dstoff = d - timedelta(days=d.weekday() + 1)
if self.dston <= dt.replace(tzinfo=None) < self.dstoff:
return timedelta(hours=1)
else:
return timedelta(0)
def utcoffset(self, dt):
return timedelta(hours=0)
def tzname(self, dt):
return "GMT"
def get_date():
gmt = GMT()
return datetime.now(tz=gmt).strftime('%a, %d %b %Y %H:%M:%S GMT')
def get_headers(auth_string):
# highlight next line
dig = hmac.new(bytes('SECRET_KEY', 'latin-1'),
msg=bytes(auth_string, 'latin-1'),
digestmod=hashlib.sha256).digest()
signature = base64.b64encode(dig).decode('utf-8')
headers = {'Date': str(get_date()),
'Authorization': 'TAM ' + 'CLIENT_ID' + ':' + signature}
return headers
# https://mqs.tamu.edu/rest/docs/
def data_from_netid(uin):
url = 'https://mqs.tamu.edu/rest/directory/uin/%s/json/' % (uin,)
auth_string = '/rest/directory/uin/%s/json/\n%s\n%s' % \
(uin,
str(get_date()),
'CLIENT_ID',)
try:
response = requests.get(url, headers=get_headers(auth_string))
data = response.json()
return data
except:
print('Error getting uin from API: %s' % (uin))
return response
print(data_from_netid("UIN"))