Skip to content

Latest commit

 

History

History
127 lines (90 loc) · 5.63 KB

File metadata and controls

127 lines (90 loc) · 5.63 KB

👉 JWT Authentication to Event Grid

Configure Event Grid Namespaces | Run the Sample |

This scenario showcases how to authenticate to Azure Event Grid via JWT authentication using MQTT 5. This scenario is identical to getting_started in functionality.

JWT authentication is documented in Microsoft Entra JWT authentication and Azure RBAC authorization to publish or subscribe MQTT messages from Event Grid documentation.

To keep the scenario simple, a single client called "sample_client" publishes and subscribes to MQTT messages on topics shown in the table.

Client Role Operation Topic/Topic Filter
sample_client publisher publish jwt/topic1
sample_client subscriber subscribe jwt/+

Prerequisites

This sample involves configuring Event Grid per the specifications in setup, but does not require CA certificates to be configured.

Create a topic space

Run the commands to create the "jwt" topic space, and the two permission bindings that provide publish and subscribe access to $all client group on the samples topic space.

# from folder scenarios/jwt_authentication
source ../../az.env

az resource create --id "$res_id/topicSpaces/jwt" --properties '{
    "topicTemplates": ["jwt/#"]
}'

Create the .env file with connection details

The required .env files can be configured manually, we provide the script below as a reference to create those files, as they are ignored from git.

# from folder scenarios/jwt_authentication
source ../../az.env
host_name=$(az resource show --ids $res_id --query "properties.topicSpacesConfiguration.hostname" -o tsv)

echo "MQTT_HOST_NAME=$host_name" > .env
echo "MQTT_USERNAME=sample_client" >> .env
echo "MQTT_CLIENT_ID=sample_client" >> .env
echo "AZURE_CLIENT_ID=<your client Id>" >> .env
echo "AZURE_TENANT_ID=<your tennant Id>" >> .env
echo "AZURE_CLIENT_SECRET<your client secret>" >> .env

🔒 Create an Identity in Microsoft Entra ID

Event Grid namespaces supports JWT authentication for Managed Identities and Service principals only:

  • Managed Identity. You can use a Managed identity provided by many Azure services, such as Azure Container Apps, Azure Container Instances, Azure Kubernetes Services or Azure Web Apps, full list is available here.

  • Service Principal. You can create your own Service Principal by creating an Application Registration in Microsoft Entra ID.

To create the service principal and the secret using the Azure CLI:

clientId=$(az ad app create --display-name "MyMqttSamplesApp" --query appId -o tsv)
spId=$(az ad sp create --id $clientId --query id -o tsv)
az ad app credential reset --id $clientId --append

take note of the appId, password and tenant values returned from the previous command.

Note. You can use these values as environment variables for dotnet by using the launchSettings.json file

Assign RBAC permissions

In Azure EventGrid Namespaces, assign permissions to the Microsoft Entra ID identity using the built-in roles Event Grid Topic Spaces Publisher/Subscriber.

# from folder scenarios/jwt_authentication
source ../../az.env

az role assignment create \
  --assignee $spId \
  --role "EventGrid TopicSpaces Publisher" \
  --scope $res_id

az role assignment create \
  --assignee $spId \
  --role "EventGrid TopicSpaces Subscriber" \
  --scope $res_id

By assigning these roles to an Azure subscription, it allows that subscription to communicate with any Topic Space within an instance of Event Grid owned by the specified Service Principal (e.g., if these roles are assigned at a subscription level, any Topic Space of an Event Grid under the given subscription could be subscribed/published to).

An alternative to using Azure CLI is the Azure Portal:

  1. Locate the resource group that contains the desired instance of Event Grid.
  2. Navigate to Access control (IAM) blade.
  3. Under Role Assignments, click Add, and assign Event Grid Topic Spaces Publisher/Subscriber roles.
  4. Assign the role to the desired Azure account, and click Review + Assign.

🎲 Run the Sample

All samples are designed to be executed from the root scenario folder.

dotnet

To build the dotnet sample run:

# from folder scenarios/jwt_authenticaton
dotnet build dotnet/jwt_authentication.sln 

To run the dotnet sample:

 dotnet/jwt_authentication/bin/Debug/net7.0/jwt_authentication

Connecting over WebSocket

To connect using WebSockets, modify client's ConnectAsync() call as follows:

MqttClientConnectResult connAck = await mqttClient!.ConnectAsync(new MqttClientOptionsBuilder()
    .WithClientId("sample_client")
    //.WithTcpServer(hostname, 8883)
    .WithWebSocketServer(b => b.WithUri($"{hostname}:443/mqtt"))
    .WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)
    .WithAuthentication("OAUTH2-JWT", Encoding.UTF8.GetBytes(jwt.Token))
    .WithTlsOptions(new MqttClientTlsOptions() { UseTls = true })
    .Build());

Note that it is required to use port 443 for websocket connections. To learn more about this flow visit the documentation.