Microsoft Event Hubs allows Shared Access Signatures (SAS) tokens for accessing event hubs.
The token signing is described here:
https://docs.microsoft.com/en-us/azure/event-hubs/authenticate-shared-access-signature
It uses HMAC SHA256 as a signing algorithm.
The token structure is:
'SharedAccessSignature sr=' + encoded + '&sig=' + encodeURIComponent(hash) + '&se=' + ttl + '&skn=' + saName;
where
field | meaning |
sr | URI of the resource being accessed. |
sig | HMACSHA256 Signature computed over the resource URI (scope as described in the previous section) and the string representation of the token expiry instant, separated by a newline character (\n). |
se | Token expiry instant. Integer reflecting seconds since epoch |
skn | SAS key name |
How can I create such a token within Apigee? I don't see any standard policy that would support that kind of signing.
Solved! Go to Solution.
Brian, I think you can use this callout:
https://github.com/DinoChiesa/Apigee-Java-AzureEventHubs-SasToken
with this configuration:
<JavaCallout name='Java-GenerateSasToken-1'> <Properties> <Property name="resource-uri">contoso.servicebus.windows.net/hub1</Property> <Property name="expiry">7d</Property> <Property name="key">{private.shared_access_key}</Property> <Property name="key-name">{encodedkey_name}</Property> </Properties> <ClassName>com.google.apigee.edgecallouts.azureeventhubs.SasCallout</ClassName> <ResourceURL>java://apigee-azure-eventhubs-sas-callout-20191218.jar</ResourceURL> </JavaCallout>
It worked for me with the test instance you gave me.
Some further comments.
"SAS" refers to Shared Access Signature, which is Microsoft's convention for applying HMAC, in other words a keyed-hash message authentication code, to produce a cryptographic signature for authentication purposes. HMAC is easy to compute in Apigee with the builtin features, like the HMAC policy and the hmac static function. But, the structure of Microsoft's token is not a simple encoded HMAC. Instead it is a series of parameters (sr, se, skn, sig) encoded in the x-www-form-urlencoded format.
An authorization header with a valid "token" looks like this:
Authorization: SharedAccessSignature sr=https%3A%2F%2Fcontoso.servicebus.windows.net%2F&sig=aCmxWdfkSEOEEh7B8Ju3Wc32rxkuOcxK5YUFPaI%2BMCY%3D&se=1585172644&skn=key1
While producing an HMAC is relatively straightforward in Apigee just using the builtin hmac capabilities and AssignMessage, assembling and encoding all of the pieces required by Microsoft for a SAS token can be sort of tedious. Therefore, I built this callout to aid in the assembly. It's pretty simple. The core of the Java logic is:
Mac hmac = Mac.getInstance("HmacSHA256"); hmac.init(new SecretKeySpec(keyBytes, "HmacSHA256")); String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry; byte[] hmacBytes = hmac.doFinal(stringToSign.getBytes("UTF-8")); String hmacB64 = new String(base64Encoder.encode(hmacBytes), "UTF-8"); String sasToken = String.format( "SharedAccessSignature sr=%s&sig=%s&se=%d&skn=%s", URLEncoder.encode(resourceUri, "UTF-8"), URLEncoder.encode(hmacB64, "UTF-8"), expiry, keyName);