对node.js中的Azure Log Analytics授权标头进行编码/encryption

我一直试图让日志收集器API工作在一个node.js Azurefunction,但坚持403 /禁止错误,这表明我没有正确地形成授权头。 完整的代码在这里是一个github仓库:

https://github.com/sportsmgmt-labs/Azure-Log-Analytics-Node-Function

Data Collector API文档位于以下位置:

https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-data-collector-api

授权标题应格式化如下:

授权:SharedKey {WorkspaceID}:{签名}

签名是这样编码/encryption的:

Base64编码(HMAC-SHA256(UTF8(StringToSign)))

这是我创build授权标头的代码:

var contentLength = Buffer.byteLength(req.body['log-entry'], 'utf8'); var authorization = 'POST\n' + contentLength + '\napplication/json\nx-ms-date:' + processingDate + '\n/api/logs'; // encode string using Base64(HMAC-SHA256(UTF8(StringToSign))) authorization = crypto.createHmac('sha256', sharedKey).update(authorization.toString('utf8')).digest('base64'); authorization = 'Authorization: SharedKey ' + workspaceId + ':' + authorization; 

服务器的响应是:

{“错误”:“InvalidAuthorization”,“Message”:“授权标头中指定了无效的scheme”}

有人能帮我理解我在做什么错吗? 谢谢!

编辑:这是执行此操作的Python代码:

 def build_signature(customer_id, shared_key, date, content_length, method, content_type, resource): x_headers = 'x-ms-date:' + date string_to_hash = method + "\n" + str(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource bytes_to_hash = bytes(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 {}:{}".format(customer_id,encoded_hash) return authorization 

…和C#代码:

  static void Main() { // Create a hash for the API signature var datestring = DateTime.UtcNow.ToString("r"); string stringToHash = "POST\n" + json.Length + "\napplication/json\n" + "x-ms-date:" + datestring + "\n/api/logs"; string hashedString = BuildSignature(stringToHash, sharedKey); string signature = "SharedKey " + customerId + ":" + hashedString; PostData(signature, datestring, json); } // Build the API signature public static string BuildSignature(string message, string secret) { var encoding = new System.Text.ASCIIEncoding(); byte[] keyByte = Convert.FromBase64String(secret); byte[] messageBytes = encoding.GetBytes(message); using (var hmacsha256 = new HMACSHA256(keyByte)) { byte[] hash = hmacsha256.ComputeHash(messageBytes); return Convert.ToBase64String(hash); } } 

您需要先解码共享密钥。 请尝试更改以下代码行:

 authorization = crypto.createHmac('sha256', sharedKey).update(authorization.toString('utf8')).digest('base64'); authorization = 'Authorization: SharedKey ' + workspaceId + ':' + authorization; 

至:

 authorization = crypto.createHmac('sha256', new Buffer(sharedKey, 'base64')).update(authorization, 'utf-8').digest('base64'); var signature = 'SharedKey ' + workspaceId + ':' + authorization; 

然后请求头将如下所示:

 headers: { 'content-type': 'application/json', 'Authorization': signature, 'Log-Type': <log_type>, 'x-ms-date': processingDate }, 

Node.js代码示例

 var request = require('request'); var crypto = require('crypto'); // Azure Log Analysis credentials var workspaceId = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'; var sharedKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; var apiVersion = '2016-04-01'; var processingDate = new Date().toUTCString(); var jsonData = [{ "slot_ID": 12345, "ID": "5cdad72f-c848-4df0-8aaa-ffe033e75d57", "availability_Value": 100, "performance_Value": 6.954, "measurement_Name": "last_one_hour", "duration": 3600, "warning_Threshold": 0, "critical_Threshold": 0, "IsActive": "true" }, { "slot_ID": 67890, "ID": "b6bee458-fb65-492e-996d-61c4d7fbb942", "availability_Value": 100, "performance_Value": 3.379, "measurement_Name": "last_one_hour", "duration": 3600, "warning_Threshold": 0, "critical_Threshold": 0, "IsActive": "false" }] var body = JSON.stringify(jsonData); var contentLength = Buffer.byteLength(body, 'utf8'); var stringToSign = 'POST\n' + contentLength + '\napplication/json\nx-ms-date:' + processingDate + '\n/api/logs'; var signature = crypto.createHmac('sha256', new Buffer(sharedKey, 'base64')).update(stringToSign, 'utf-8').digest('base64'); var authorization = 'SharedKey ' + workspaceId + ':' + signature; var headers = { "content-type": "application/json", "Authorization": authorization, "Log-Type": 'WebMonitorTest', "x-ms-date": processingDate }; var url = 'https://' + workspaceId + '.ods.opinsights.azure.com/api/logs?api-version=' + apiVersion; request.post({url: url, headers: headers, body: body}, function (error, response, body) { console.log('error:', error); console.log('statusCode:', response && response.statusCode); console.log('body:', body); });