Skip to content

Commit d7541c9

Browse files
author
Jill Grant
authored
Merge pull request #281411 from Y-Sindo/mqtt
Add MQTT for WebPubSub
2 parents f182342 + 81f557b commit d7541c9

18 files changed

+1514
-33
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
title: How to connect MQTT clients to Azure Web PubSub
3+
description: How to connect MQTT clients to Azure Web PubSub
4+
author: Y-Sindo
5+
ms.author: zityang
6+
ms.service: azure-web-pubsub
7+
ms.date: 06/17/2024
8+
ms.topic: how-to
9+
---
10+
11+
# How to connect MQTT clients to Azure Web PubSub
12+
13+
MQTT is a lightweight pub/sub messaging protocol designed for devices with constrained resources.
14+
15+
In this article, we introduce how to connect MQTT clients to the service, so that the clients can publish and subscribe messages.
16+
17+
## Connection parameters
18+
19+
WebSocket connection URI: `wss://{serviceName}.webpubsub.azure.com/clients/mqtt/hubs/{hub}?access_token={token}`.
20+
21+
* {hub} is a mandatory parameter that provides isolation for different applications.
22+
* {token} is required by default. Alternatively, you can include the token in the `Authorization` header in the format `Bearer {token}`. You can bypass the token requirement by enabling anonymous access to the hub. <!--TODO MQTT allow anonymous access to the hub-->
23+
24+
If client library doesn't accept a URI, then you probably need to split the information in the URI into multiple parameters:
25+
26+
* Host: `{serviceName}.webpubsub.azure.com`
27+
* Path: `/clients/mqtt/hubs/{hub}?access_token={token}`
28+
* Port: 443
29+
* Transport: WebSockets with [TLS](https://wikipedia.org/wiki/Transport_Layer_Security).
30+
31+
[!INCLUDE [MQTT-Connection-parameters](includes/mqtt-connection-parameters.md)]
32+
33+
By default MQTT clients don't have any permissions to publish or subscribe to any topics. You need to grant [permissions](#permissions) to MQTT clients.
34+
35+
## Permissions
36+
37+
A client can publish to other clients only when it's *authorized* to do so. A client's permissions can be granted when it's being connected or during the lifetime of the connection.
38+
39+
| Role | Permission |
40+
|---|---|
41+
| Not specified | The client can send event requests. |
42+
| `webpubsub.joinLeaveGroup` | The client can join or leave any group. |
43+
| `webpubsub.sendToGroup` | The client can publish messages to any group. |
44+
| `webpubsub.joinLeaveGroup.<group>` | The client can join or leave group `<group>`. |
45+
| `webpubsub.sendToGroup.<group>` | The client can publish messages to group `<group>`. |
46+
| | |
47+
48+
## Authentication and authorization
49+
50+
There are two workflows supported by Web PubSub to authenticate and authorize MQTT clients, so that they have proper permissions.
51+
52+
These workflows can be used individually or in combination. If they're used in together, the auth result in the latter workflow would be honored by the service.
53+
54+
### 1. JWT workflow
55+
56+
This is the default workflow, shown as follows:
57+
58+
![Diagram of MQTT auth workflow with JWT.](./media/howto-connect-mqtt-websocket-client/mqtt-jwt-auth-workflow.png)
59+
60+
1. The client negotiates with your auth server. The auth server contains the authorization middleware, which handles the client request and signs a JWT for the client to connect to the service.
61+
1. The auth server returns the JWT to the client.
62+
1. The client tries to connect to the Web PubSub service with the JWT token returned from the auth server. The token can be in either the query string, as `/clients/mqtt/hubs/{hub}?access_token={token}`, or the `Authorization` header, as `Authorization: Bearer {token}`.
63+
64+
#### Supported claims
65+
You could also configure properties for the client connection when generating the access token by specifying special claims inside the JWT token:
66+
67+
| Description | Claim type | Claim value | Notes |
68+
| --- | --- | --- | --- |
69+
| The [permissions](#permissions) the client connection initially has | `role` | the role value defined in [permissions](#permissions) | Specify multiple `role` claims if the client has multiple permissions. |
70+
| The lifetime of the token | `exp` | the expiration time | The `exp` (expiration time) claim identifies the expiration time on or after which the token MUST NOT be accepted for processing. |
71+
| The initial groups that the client connection joins once it connects to Azure Web PubSub | `group` | the group to join | Specify multiple `group` claims if the client joins multiple groups. |
72+
| The `userId` for the client connection | `sub` | the userId | Only one `sub` claim is allowed. |
73+
74+
You could also add custom claims into the access token, and these values are preserved as the `claims` property in [connect upstream request body](./reference-mqtt-cloud-events.md#system-connect-event).
75+
76+
[Server SDKs](./howto-generate-client-access-url.md#generate-from-service-sdk) provides APIs to generate the access token for MQTT clients. Note that you must specify the client protocol to `Mqtt`.
77+
78+
# [JavaScript](#tab/javascript)
79+
80+
1. Follow [Getting started with server SDK](./reference-server-sdk-js.md#getting-started) to create a `WebPubSubServiceClient` object `service`
81+
82+
> [!NOTE]
83+
> Generating MQTT client access URL is supported since [version 1.1.3](https://www.npmjs.com/package/@azure/web-pubsub/v/1.1.3?activeTab=versions).
84+
85+
2. Generate Client Access URL by calling `WebPubSubServiceClient.getClientAccessToken`:
86+
87+
```js
88+
let token = await serviceClient.getClientAccessToken({ clientProtocol: "mqtt" });
89+
```
90+
91+
# [C#](#tab/csharp)
92+
93+
1. Follow [Getting started with server SDK](./reference-server-sdk-csharp.md#getting-started) to create a `WebPubSubServiceClient` object `service`
94+
95+
> [!NOTE]
96+
> Generating MQTT client access URL is supported since [version 1.4.0](https://www.nuget.org/packages/Azure.Messaging.WebPubSub/1.4.0).
97+
98+
2. Generate Client Access URL by calling `WebPubSubServiceClient.GetClientAccessUri`:
99+
100+
```csharp
101+
var url = service.GetClientAccessUri(clientProtocol: WebPubSubClientProtocol.Mqtt);
102+
```
103+
104+
# [Python](#tab/python)
105+
106+
1. Follow [Getting started with server SDK](./reference-server-sdk-python.md#install-the-package) to create a `WebPubSubServiceClient` object `service`
107+
108+
> [!NOTE]
109+
> Generating MQTT client access URL is supported since [version 1.2.0](https://pypi.org/project/azure-messaging-webpubsubservice/1.2.0/).
110+
111+
2. Generate Client Access URL by calling `WebPubSubServiceClient.get_client_access_token`:
112+
113+
```python
114+
token = service.get_client_access_token(client_protocol="MQTT")
115+
```
116+
117+
# [Java](#tab/java)
118+
119+
1. Follow [Getting started with server SDK](./reference-server-sdk-java.md#getting-started) to create a `WebPubSubServiceClient` object `service`
120+
121+
> [!NOTE]
122+
> Generating MQTT client access URL is supported since [version 1.3.0](https://central.sonatype.com/artifact/com.azure/azure-messaging-webpubsub/1.3.0).
123+
124+
125+
2. Generate Client Access URL by calling `WebPubSubServiceClient.getClientAccessToken`:
126+
127+
```java
128+
GetClientAccessTokenOptions option = new GetClientAccessTokenOptions();
129+
option.setWebPubSubClientProtocol(WebPubSubClientProtocol.MQTT);
130+
WebPubSubClientAccessToken token = service.getClientAccessToken(option);
131+
```
132+
---
133+
134+
### 2. Upstream server workflow
135+
136+
The MQTT client sends an MQTT CONNECT packet after it establishes a WebSocket connection with the service, then the service calls an API in the upstream server. The upstream server can auth the client according to the username and password fields in the MQTT connection request, and the TLS certificate from the client.
137+
138+
![Diagram of MQTT auth workflow with upstream server](./media/howto-connect-mqtt-websocket-client/mqtt-upstream-auth-workflow.png)
139+
140+
This workflow needs explicit configuration.
141+
* [Tutorial - Authenticate and authorize MQTT clients based on client certificates](./tutorial-upstream-auth-mqtt-client.md)
142+
* For details about how to use upstream server to auth the clients, see [How to configure event handler](./howto-develop-eventhandler.md)
143+
144+
## Troubleshooting
145+
146+
If you're experiencing failure of connection, or unable to publish or subscribe messages, please check the reason code / return code from the service, or see [How to troubleshoot with resource logs](./howto-troubleshoot-resource-logs.md).
147+
148+
149+

articles/azure-web-pubsub/howto-develop-event-listener.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ ms.date: 09/30/2022
1212

1313
> [!NOTE]
1414
> Event listener feature is in preview.
15+
> Sending MQTT client events to event listener is not supported yet.
1516
1617
## Overview
1718

@@ -76,7 +77,7 @@ Find your Azure Web PubSub service from **Azure portal**. Navigate to **Identity
7677

7778
In this article, you learned how event listeners work and how to configure an event listener with an event hub endpoint. To learn the data format sent to Event Hubs, read the following specification.
7879

79-
> [!div class="nextstepaction"]
80+
> [!div class="nextstepaction"]
8081
> [Specification: CloudEvents AMQP extension for Azure Web PubSub](./reference-cloud-events-amqp.md)
8182
8283
<!--TODO: Add demo-->

articles/azure-web-pubsub/howto-generate-client-access-url.md

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,24 @@ ms.topic: how-to
1010

1111
# How to generate client access URL for the clients
1212

13-
A client, be it a browser 💻, a mobile app 📱, or an IoT device 💡, uses a **Client Access URL** to connect and authenticate with your resource. This URL follows a pattern of `wss://<service_name>.webpubsub.azure.com/client/hubs/<hub_name>?access_token=<token>`. This article shows you several ways to get the Client Access URL.
13+
A client, be it a browser 💻, a mobile app 📱, or an IoT device 💡, uses a **Client Access URL** to connect and authenticate with your resource.
14+
15+
The URL follows the below pattern:
16+
* For MQTT clients, it's `wss://<service_name>.webpubsub.azure.com/clients/mqtt/hubs/<hub_name>?access_token=<token>`.
17+
* For all other clients, it's `wss://<service_name>.webpubsub.azure.com/client/hubs/<hub_name>?access_token=<token>`.
18+
19+
This article shows you several ways to get the Client Access URL.
1420

1521
- For quick start, copy one from the Azure portal
16-
- For development, generate the value using [Web PubSub server SDK](./reference-server-sdk-js.md)
22+
- For development, generate the value using [Web PubSub server SDK](#generate-from-service-sdk)
1723
- If you're using Microsoft Entra ID, you can also invoke the [Generate Client Token REST API](/rest/api/webpubsub/dataplane/web-pub-sub/generate-client-token)
1824

1925
## Copy from the Azure portal
2026

2127
In the Keys tab in Azure portal, there's a Client URL Generator tool to quickly generate a Client Access URL for you, as shown in the following diagram. Values input here aren't stored.
2228

29+
Note that for MQTT clients, you should select "MQTT Client" in the dropdown menu in front of the "Client Access URL" text box.
30+
2331
:::image type="content" source="./media/howto-websocket-connect/generate-client-url.png" alt-text="Screenshot of the Web PubSub Client URL Generator.":::
2432

2533
## Generate from service SDK
@@ -32,6 +40,12 @@ The same Client Access URL can be generated by using the Web PubSub server SDK.
3240

3341
2. Generate Client Access URL by calling `WebPubSubServiceClient.getClientAccessToken`:
3442

43+
- Generate MQTT client access token
44+
45+
```js
46+
let token = await serviceClient.getClientAccessToken({ clientProtocol: "mqtt" });
47+
```
48+
3549
- Configure user ID
3650

3751
```js
@@ -76,6 +90,12 @@ The same Client Access URL can be generated by using the Web PubSub server SDK.
7690

7791
2. Generate Client Access URL by calling `WebPubSubServiceClient.GetClientAccessUri`:
7892

93+
- Generate MQTT client access token
94+
95+
```csharp
96+
var url = service.GetClientAccessUri(clientProtocol: WebPubSubClientProtocol.Mqtt);
97+
```
98+
7999
- Configure user ID
80100

81101
```csharp
@@ -112,6 +132,12 @@ The same Client Access URL can be generated by using the Web PubSub server SDK.
112132

113133
2. Generate Client Access URL by calling `WebPubSubServiceClient.get_client_access_token`:
114134

135+
- Generate MQTT client access token
136+
137+
```python
138+
token = service.get_client_access_token(client_protocol="MQTT")
139+
```
140+
115141
- Configure user ID
116142

117143
```python
@@ -148,7 +174,15 @@ The same Client Access URL can be generated by using the Web PubSub server SDK.
148174

149175
2. Generate Client Access URL by calling `WebPubSubServiceClient.getClientAccessToken`:
150176

151-
- Configure user ID
177+
- Generate MQTT client access token
178+
179+
```java
180+
GetClientAccessTokenOptions option = new GetClientAccessTokenOptions();
181+
option.setWebPubSubClientProtocol(WebPubSubClientProtocol.MQTT);
182+
WebPubSubClientAccessToken token = service.getClientAccessToken(option);
183+
```
184+
185+
- Configure user ID
152186

153187
```java
154188
GetClientAccessTokenOptions option = new GetClientAccessTokenOptions();
@@ -192,18 +226,18 @@ The same Client Access URL can be generated by using the Web PubSub server SDK.
192226

193227
In real-world code, we usually have a server side to host the logic generating the Client Access URL. When a client request comes in, the server side can use the general authentication/authorization workflow to validate the client request. Only valid client requests can get the Client Access URL back.
194228

195-
## Invoke the Generate Client Token REST API
229+
## Invoke the "Generate Client Token" REST API
196230

197231
You can enable Microsoft Entra ID in your service and use the Microsoft Entra token to invoke [Generate Client Token rest API](/rest/api/webpubsub/dataplane/web-pub-sub/generate-client-token) to get the token for the client to use.
198232

199233
1. Follow [Authorize from application](./howto-authorize-from-application.md) to enable Microsoft Entra ID.
200234
2. Follow [Get Microsoft Entra token](./howto-authorize-from-application.md#use-postman-to-get-the-microsoft-entra-token) to get the Microsoft Entra token with Postman.
201235
3. Use the Microsoft Entra token to invoke `:generateToken` with Postman:
202-
236+
203237
> [!NOTE]
204238
> Please use the latest version of Postman. Old versions of Postman have [some issue](https://github.com/postmanlabs/postman-app-support/issues/3994#issuecomment-893453089) supporting colon `:` in path.
205239

206-
1. For the URI, enter `https://{Endpoint}/api/hubs/{hub}/:generateToken?api-version=2022-11-01`
240+
1. For the URI, enter `https://{Endpoint}/api/hubs/{hub}/:generateToken?api-version=2024-01-01`. If you'd like to generate token for MQTT clients, append query parameter `&clientType=mqtt` to the URL.
207241
2. On the **Auth** tab, select **Bearer Token** and paste the Microsoft Entra token fetched in the previous step
208242
3. Select **Send** and you see the Client Access Token in the response:
209243
@@ -212,5 +246,3 @@ You can enable Microsoft Entra ID in your service and use the Microsoft Entra to
212246
"token": "ABCDEFG.ABC.ABC"
213247
}
214248
```
215-
216-
5. The Client Access URI is in the format of `wss://<endpoint>/client/hubs/<hub_name>?access_token=<token>`
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
author: Y-Sindo
3+
ms.author: zityang
4+
ms.service: azure-web-pubsub
5+
ms.topic: include
6+
ms.date: 06/22/2024
7+
---
8+
9+
There are some limitations you should follow in your [MQTT](https://mqtt.org/mqtt-specification/) clients, otherwise the connection will be rejected. These MQTT protocol parameters include:
10+
* Protocol versions: 3.1.1 or 5.0.
11+
* Client ID format
12+
* Allowed characters: 0-9, a-z, A-Z
13+
* Length is between 1 and 128
14+
* Keep-alive interval for MQTT 3.1.1: 1 - 180 seconds
15+
* Last-will Topic format: Not empty, and contains at least one nonwhitespace character. The max length is 1024.
16+
* Last-will message size: up to 2,000 bytes
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
author: Y-Sindo
3+
ms.author: zityang
4+
ms.service: azure-web-pubsub
5+
ms.topic: include
6+
ms.date: 07/19/2024
7+
---
8+
9+
| MQTT terms| Corresponding Web PubSub terms | Relationship |
10+
| --- | --- | --- |
11+
| Server/MQTT Broker | Web PubSub Service | Web PubSub service work as MQTT brokers to serve MQTT connections. Please note that we usually use the term *server* to refer to the upstream server instead of the MQTT brokers in the documents. |
12+
| Session | Connection | *Connection* in Web PubSub is a logical concept that represents a stateful relationship between the client and service, and one *Connection* is corresponding to one *Session*. Usually these two words are interchangeable. |
13+
| Subscribe To A Topic | Join A Group | These two actions have the same effect: the client will receive messages from that topic or group. Topic name is the group name. |
14+
| Publish Message To A Topic | Send Message To A Group | These two actions have the same effect: the client who subscribes to that topic or belong to that group will receive the message |
15+
| Client ID | Connection ID | *Connection ID* identifies a *Connection* to Web PubSub. We use the *Client ID* as the *Connection ID* of MQTT connections in Web PubSub. |
17.6 KB
Loading
20.9 KB
Loading
4.13 KB
Loading
40 KB
Loading
44.7 KB
Loading

0 commit comments

Comments
 (0)