Skip to content

Commit

Permalink
[#1078] add HMAC signing to sidebar and include examples section
Browse files Browse the repository at this point in the history
Signed-off-by: Florian Fendt <Florian.Fendt@bosch.io>
  • Loading branch information
ffendt committed Jun 10, 2021
1 parent 5af4624 commit ae2a0b8
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ entries:
- title: SSH tunneling
url: /connectivity-ssh-tunneling.html
output: web
- title: HMAC signing
url: /connectivity-hmac-signing.html
output: web

- title: Client SDK
output: web
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ in the fields `uri`, `credentials.parameters.sharedKeyName`, `credentials.parame
"id": "60d193e3-2639-415b-af29-0e337741141d",
"name": "Azure IoT Hub HTTP",
"connectionType": "http-push",
"connectionStatus": "opened",
"connectionStatus": "open",
"uri": "https://my-hub.azure-devices.net:443",
"sources": [],
"targets": [{
Expand Down Expand Up @@ -277,7 +277,7 @@ from your Azure Service Bus subscription in the fields `uri`, `credentials.param
"id": "adec2846-4d11-4e0a-b456-d8bfc2192fc6",
"name": "Azure Service Bus HTTP",
"connectionType": "http-push",
"connectionStatus": "closed",
"connectionStatus": "open",
"uri": "https://my-bus.servicebus.windows.net:443",
"sources": [],
"targets": [{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: HMAC request signing
title: HMAC signing
keywords: hmac, hmac-sha256, authorization, azure, aws, azure iot hub, azure service bus, azure monitor, aws version 4 signing, aws sns, signing
tags: [connectivity]
permalink: connectivity-hmac-signing.html
---

## HMAC request signing
## HMAC signing

Ditto provides an extensible framework for HMAC-based request signing authentication processes for HTTP Push and
Ditto provides an extensible framework for HMAC-based signing authentication processes for HTTP Push and
AMQP 1.0 connections. Three algorithms are available out of the box:

- `aws4-hmac-sha256` (HTTP Push only): [Version 4 request signing](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) for Amazon Web Services (AWS)
Expand Down Expand Up @@ -131,3 +131,221 @@ and which interface needs to be implemented.
| ------------------------ | -------------------- | ------------------- |
| Config path | `ditto.connectivity.connection.http-push.hmac-algorithms` | `ditto.connectivity.connection.amqp10.hmac-algorithms` |
| Class to implement | [HttpRequestSigningFactory](https://github.com/eclipse/ditto/blob/master/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/httppush/HttpRequestSigningFactory.java) | [AmqpConnectionSigningFactory](https://github.com/eclipse/ditto/blob/master/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConnectionSigningFactory.java) |


### Example integrations

#### AWS SNS

#### AWS S3

#### Azure Monitor Data Collector HTTP API

#### Azure IoT Hub HTTP API

What follows is an example of a connections which forwards live messages sent to things as direct method calls to
Azure IoT Hub via HTTP. You'll receive the response of the direct method call.
The placeholders in `<angle brackets>` need to be replaced.

{%raw%}
```json
{
"id": "00000000-0000-0000-0000-000000000000",
"name": "Azure IoT Hub HTTP",
"connectionType": "http-push",
"connectionStatus": "open",
"uri": "https://<hostname>:443",
"sources": [],
"targets": [{
"address": "POST:/twins/{{ thing:id }}/methods?api-version=2018-06-30",
"topics": ["_/_/things/live/messages"],
"authorizationContext": ["integration:ditto"],
"issuedAcknowledgementLabel": "live-response",
"headerMapping": {},
"payloadMapping": ["javascript"]
}
],
"clientCount": 1,
"failoverEnabled": true,
"validateCertificates": true,
"processorPoolSize": 5,
"specificConfig": {
"parallelism": "1"
},
"mappingDefinitions": {
"javascript": {
"mappingEngine": "JavaScript",
"options": {
"incomingScript": "function mapToDittoProtocolMsg(\n headers,\n textPayload,\n bytePayload,\n contentType\n) {\n\n if (contentType === 'application/vnd.eclipse.ditto+json') {\n return JSON.parse(textPayload);\n } else if (contentType === 'application/octet-stream') {\n try {\n return JSON.parse(Ditto.arrayBufferToString(bytePayload));\n } catch (e) {\n return null;\n }\n }\n return null;\n}\n",
"outgoingScript": "function mapFromDittoProtocolMsg(\n namespace,\n name,\n group,\n channel,\n criterion,\n action,\n path,\n dittoHeaders,\n value,\n status,\n extra\n) {\n\n let headers = dittoHeaders;\n let textPayload = JSON.stringify(value);\n let bytePayload = null;\n let contentType = 'application/json';\n\n return Ditto.buildExternalMsg(\n headers, // The external headers Object containing header values\n textPayload, // The external mapped String\n bytePayload, // The external mapped byte[]\n contentType // The returned Content-Type\n );\n}\n",
"loadBytebufferJS": "false",
"loadLongJS": "false"
}
}
},
"credentials": {
"type": "hmac",
"algorithm": "az-sasl",
"parameters": {
"sharedKeyName": "<shared-access-policy-name>",
"sharedKey": "<shared-access-key>",
"endpoint": "<hostname>"
}
},
"tags": []
}
```
{%endraw%}


Required parameters:
* `<hostname>`: The hostname of your iot hub instance. E.g. `my-hub.azure-devices.net`.
* `<shared-access-policy-name>`: The name of the (Azure IoT Hub) shared access policy, which has the `Service connect` permission. E.g. `service`.
* `<shared-access-key>`: The primary or secondary key of above policy. E.g. `theKey`.

The `outgoingScript` provides JavaScript payload mapping which maps the outgoing ditto protocol message into a plain
`application/json` message, which contains the value of the original ditto protocol message:
```javascript
function mapFromDittoProtocolMsg(
namespace,
name,
group,
channel,
criterion,
action,
path,
dittoHeaders,
value,
status,
extra
) {

let headers = dittoHeaders;
let textPayload = JSON.stringify(value);
let bytePayload = null;
let contentType = 'application/json';

return Ditto.buildExternalMsg(
headers, // The external headers Object containing header values
textPayload, // The external mapped String
bytePayload, // The external mapped byte[]
contentType // The returned Content-Type
);
}
```

This is required since Azure IoT Hub direct methods require a [specific format](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-direct-methods#invoke-a-direct-method-from-a-back-end-app):
```json
{
"methodName": "reboot",
"responseTimeoutInSeconds": 200,
"payload": {
"input1": "someInput",
"input2": "anotherInput"
}
}
```

Send live messages to things in this format and with the above shown payload mapping, they can successfully invoke
the direct method on their respective devices.

#### Azure IoT Hub AMQP API

What follows is an example of a connections which forwards live messages sent to things as Cloud To Device (C2D)
messages to Azure IoT Hub via AMQP 1.0.
The placeholders in `<angle brackets>` need to be replaced.

{%raw%}
```json
{
"id": "00000000-0000-0000-0000-000000000000",
"name": "Azure IoT Hub AMQP",
"connectionType": "amqp-10",
"connectionStatus": "open",
"uri": "amqps://<hostname>:5671",
"sources": [],
"targets": [{
"address": "/messages/devicebound",
"topics": ["_/_/things/live/messages"],
"authorizationContext": ["integration:ditto"],
"headerMapping": {
"iothub-ack": "full",
"to": "/devices/{{thing:id}}/messages/devicebound"
}
}
],
"clientCount": 1,
"failoverEnabled": true,
"validateCertificates": true,
"processorPoolSize": 5,
"credentials": {
"type": "hmac",
"algorithm": "az-sasl",
"parameters": {
"sharedKeyName": "<shared-access-policy-name>",
"sharedKey": "<shared-access-key>",
"endpoint": "<hostname>"
}
},
"tags": []
}
```
{%endraw%}


Required parameters:
* `<hostname>`: The hostname of your iot hub instance. E.g. `my-hub.azure-devices.net`.
* `<shared-access-policy-name>`: The name of the (Azure IoT Hub) shared access policy, which has the `Service connect` permission. E.g. `service`.
* `shared-access-key>`: The primary or secondary key of above policy. E.g. `theKey`.


#### Azure Service Bus HTTP API

What follows is an example of a connection which forwards live messages sent to things to a queue in Azure Service Bus.
The placeholders in `<angle brackets>` need to be replaced.

{%raw%}
```json
{
"id": "00000000-0000-0000-0000-000000000000",
"name": "Azure Service Bus HTTP",
"connectionType": "http-push",
"connectionStatus": "open",
"uri": "https://<hostname>:443",
"sources": [],
"targets": [{
"address": "POST:/<queue-name>/messages",
"topics": ["_/_/things/live/messages"],
"authorizationContext": ["integration:ditto"],
"issuedAcknowledgementLabel": "live-response",
"headerMapping": {}
}
],
"clientCount": 1,
"failoverEnabled": true,
"validateCertificates": true,
"processorPoolSize": 5,
"specificConfig": {
"parallelism": "1"
},
"credentials": {
"type": "hmac",
"algorithm": "az-sasl",
"parameters": {
"sharedKeyName": "<shared-access-policy-name>",
"sharedKey": "<base64-encoded-shared-key>",
"endpoint": "https://<hostname>/<queue-name>"
}
},
"tags": []
}
```
{%endraw%}

Required parameters:
* `<hostname>`: The hostname of your service bus instance. E.g. `my-bus.servicebus.windows.net`.
* `<queue-name>`: The queue name to which you want to publish in your service bus instance. E.g. `my-queue`'.
* `<shared-access-policy-name>`: The name of the (Azure Service Bus) shared access policy, which has `Send` and `Listen` permissions. E.g. `RootManageSharedAccessKey`.
* `<base64-encoded-shared-key>`: The `Base64` encoded primary or secondary key of above policy. The signing work if you
encode the key with `Base64` (although it already has `Base64` encoding)`. E.g. if the primary key is `theKey`, you need to use
its encoded version `dGhlS2V5`

0 comments on commit ae2a0b8

Please sign in to comment.