Third Party Logging HMAC (Azure Log Analytics)

We are attempting to log data to Azure Log Analytics which we think can be done with a simple ServiceCallout and doing an HTTP Post but the problem we are running into is generating the SHA256 HMAC for authorization. Are there any examples on how to generate this to use in the header for the HTTP Post? We've tried doing this in javascript but are running into issues without having access to various libraries that are generally used. Any ideas?

Solved Solved
0 5 728
1 ACCEPTED SOLUTION

5 REPLIES 5

Did it work?

I had actually seen this code in previous searches but wasn't sure if there was another way. We ended up going in a different direction utilizing a logging microservice that then posts to Log Analytics.

Thank you for the information

Hi, I did this using a python script and using a service call out to log to an Azure Log Analytics workspace. Code presented below.

1. Use AssignMessage policy and set the 'mybody' variable (the json log payload to send to Azure) using Assign Variable.

2. Make a call to the python script, which is as follows:

import datetime
import hashlib
import hmac
import base64


# Update the customer ID to your Log Analytics workspace ID
customer_id = 'xxxxxxxxxxxxxxx'


# For the shared key, use either the primary or the secondary Connected Sources client authentication key   
shared_key = 'xxxxxxxxxxxxxxxxx'


# The log type is the name of the event that is being submitted
log_type = 'WebMonitorTest'


# Build the API signature


date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
x_headers = 'x-ms-date:' + date
content_type = 'application/json'
content_length = len(flow.getVariable("mybody"))
method = 'POST'
resource = '/api/logs'
string_to_hash = method + "\n" + str(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource
bytes_to_hash = str(string_to_hash.encode('utf-8'))
decoded_key = base64.b64decode(shared_key)
encoded_hash = base64.b64encode(hmac.new(decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest())
authorization = "SharedKey " + customer_id + ":" + str(encoded_hash)
flow.setVariable("authorizationHeader",authorization) 
flow.setVariable("logType", log_type)
flow.setVariable("date", date)


3. Use ServiceCallOut policy to call the Azure endpoint:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="SC-LogToAzureMonitor">
    <DisplayName>SC-LogToAzureMonitor</DisplayName>
    <Properties/>
    <Request clearPayload="true" variable="myRequest">
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
        <Set>
            <Headers>
                <Header name="content-type">application/json</Header>
                <Header name="Authorization">{authorizationHeader}</Header>
                <Header name="Log-Type">{logType}</Header>
                <Header name="x-ms-date">{date}</Header>
            </Headers>
            <Payload contentType="application/json">{mybody}</Payload>
            <Verb>POST</Verb>
        </Set>
    </Request>
    <Response>calloutResponse</Response>
    <HTTPTargetConnection>
        <Properties/>
        <URL>https://{log-workspace-id}.ods.opinsights.azure.com/api/logs?api-version=2016-04-01</URL>
    </HTTPTargetConnection>
</ServiceCallout>

Whoo-hoo! Thanks for the tip.