HMAC Signature
Clients can make a request to most web services by sending an HMAC signature on the HTTP Authorization request header. A request header with an HMAC signature looks like the following:
Authorization: http://www.worldcat.org/wskey/v2/hmac/v1 clientId="tsFsoBXToV1uR8GEMJCcxz9NYpVvutsA5cJAD9cnKUc4FGYEntM6UkcIVlYp4ZhYFteVLAxOWJDUV85W", timestamp="1361306811", nonce="762343395744465450467911322335", signature="2DwPAIYqlCOH9xCHM7PSnOBoVKk/PHrHPeIGmmEK/AI=", principalID="8eaa9f92-3951-431c-975a-d7dfkd9rd131", principalIDNS="urn:oclc:wms:da"
Note: for readability the line breaks have been added between the key/value pairs, but the Authorization value should be sent as a string with no line breaks. The principal ID and principal ID namespace parameters are optional and not required by all web services.
Generating an HMAC Signature
A signature is generated by calculating a digest using the HMAC-SHA256 hashing algorithm. The inputs to the hashing algorithm include the WSKey secret and a normalized string that represents the current request.
To build the pre-hashed string concatenate the following elements separated by new line characters:
- The client’s WSKey
- A timestamp value calculated for the request in seconds.
- A nonce value generated for the request.
- The request entity-body hash if one was calculated and included in the request, otherwise, an empty string.
- The HTTP request method in upper case: HEAD, GET, POST, PUT, or DELETE
- The string literal www.oclc.org
- The string literal 443
- The string literal /wskey
- The query component of the web service request URI normalized as described in Section 3.3.1.1 of HTTP MAC authentication scheme
HMAC Signature Example
If making a GET request to the following URL
https://circ.sd00.worldcat.org/pulllist/128156?inst=128807
With the following parameters:
Key: jdfRzYZbLc8HZXFByyyLGrUqTOOmkJOAPi4tAN0E7xI3hgE2xDgwJ7YPtkwM6W3ol5yz0d0JHgE1G2Wa
Secret: UYnwZbmvf3fAXCEa0JryLQ==
Timestamp: 1361408273
Nonce: 981333313127278655903652665637
The pre-hashed string would look like the following:
jdfRzYZbLc8HZXFByyyLGrUqTOOmkJOAPi4tAN0E7xI3hgE2xDgwJ7YPtkwM6W3ol5yz0d0JHgE1G2Wa 1361408273 981333313127278655903652665637 GET www.oclc.org 443 /wskey inst=128807
Note that the line numbers are there to illustrate that there is a new line character at the end. Also note that when making requests to URLs that have no query parameters, there should only be a single newline at the end of this pre-hashed string.
After calculating the signature, it should be base64 encoded.
digest = HMAC-SHA256 ( wskey_secret, prehashed_string ) signature = base64 ( digest )
This request would generate the following Authorization header value. This example does not include body content. Even if it did, because the there is no key/value pair in the Authorization header for the entity-body hash, line 4 of the pre-hashed string is an empty string.
Example (space added for readability)
http://www.worldcat.org/wskey/v2/hmac/v1 clientId="jdfRzYZbLc8HZXFByyyLGrUqTOOmkJOAPi4tAN0E7xI3hgE2xDgwJ7YPtkwM6W3ol5yz0d0JHgE1G2Wa", timestamp="1361408273", nonce="981333313127278655903652665637", signature="5O6SRig58wqm6gqEu3oSODVte6Albon9CCvNrZHCoys="
Requests that send a nonce or timestamp used on a previous request are considered invalid.