tl;dr
-
New-AzIotHubSasToken
ではなくaz iot hub generate-sas-token
を使いましょう。 - なお、AzureRMは2020年12月でサポートが終了します
経緯
日本で展開しているサービスを中国でも展開することになりました。
Azure IoT HubにREST APIでアクセスしている箇所があったので、リソース展開後にSAS Tokenを取得したらうまく接続できませんでした。(前、どうやって作成したっけ?)
なお、以下のコマンドはすべてPowerShellです。
試したこと1: Azure PortalからAzure Cloud Shellの実行
下記画像をご覧いただくと分かる通り、中国リージョンではCloud Shellが展開されていないようです。
あ、どうしよう・・ってなりました。
試したこと2: New-AzIotHubSasToken
コマンドでSAS Token発行
たまたまPCに入っていたのがAzureRMだったのです。
というわけで、とても見事に壁にあたってしまいました。
手順
サインイン
connect-azaccount -environment azurechinacloud
中国リージョンは-environment azurechinacloud
必須です。
エンドポイントについての詳細は、Azure から独立しているクラウドでの Azure PowerShell によるストレージの管理 > エンドポイントサフィックスを参照してください。
意気揚々とIoT HubのSAS Tokenを発行します。
New-AzIotHubSasToken
-ResourceGroupName "{resourceGroupName}"
-IotHubName "{iotHubName}"
-Duration 31104000
-KeyName "iothubowner"
アクセスできるか試してみます。
Invoke-WebRequest
https://{iotHubName}.azure-devices.cn/twins/{deviceName}?api-version=2018-06-30
-Headers @{
"Authorization"="SharedAccessSignature sr={iotHubName}.azure-devices.cn&sig=x&se=x&skn=iothubowner"
}
エラーがでます
{
"Message": "ErrorCode:IotHubUnauthorizedAccess;Unauthorized",
"ExceptionMessage": "Tracking ID:00000000000000000000000000000000-G:7-TimeStamp:08/25/2020 00:00:00"
}
Unauthorized・・。
SAS Tokenが誤っていることが原因なのですが、SAS Tokenを送らなくても(空でも)同じメッセージが返されるので、最初、何が原因なのか分かりませんでした。
試したこと3: az iot hub generate-sas-token
コマンドでSAS Token発行
手順
Azure CLI(Azure PowerShell Az モジュール)をインストールします
ログインし、サブスクリプションを指定します。
az login --tenant {tenantName}
az account set --subscription {subscriptionId}
疑心暗鬼になりながらSAS Tokenを発行してみます。
az iot hub generate-sas-token -n {iotHubName}
アクセスできるか試してみます。
Invoke-WebRequest
https://{iotHubName}.azure-devices.cn/twins/{deviceName}?api-version=2018-06-30
-Headers @{
"Authorization"="SharedAccessSignature sr={iotHubName}.azure-devices.cn&sig=x&se=x&skn=iothubowner"
}
あ、うまくいきました。
StatusCode : 200
StatusDescription : OK
Content : {"deviceId":"x","etag":"x","deviceEtag":"x","status":"enabled
","statusUpdateTime":"0001-01-01T00:00:00Z","connectionState":"Disconnected","lastActivityTime":"20
20...
RawContent : HTTP/1.1 200 OK
Vary: Origin
x-ms-request-id: 00000000-0000-0000-0000-000000000000
Content-Length: 1199
Content-Type: application/json; charset=utf-8
Date: Tue, 25 Aug 2020 00:00:00 GMT
Server: ...
Forms : {}
Headers : {[Vary, Origin], [x-ms-request-id, 00000000-0000-0000-0000-000000000000], [Content-Length, 1199], [
Content-Type, application/json; charset=utf-8]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 1199
おまけ: Visual Studio Code拡張(vscode-azure-iot-toolkit)でSAS Token発行
Visual Studio Codeの拡張機能を使うと、とても簡単にSAS Tokenを発行することができます。
でもデバイスごとのSAS Tokenは、うまく動作しません。
なぜ?
デバイスツインを取得する方法
curl -X GET "https://{iotHubName}.azure-devices.cn/twins/{deviceName}?api-version=2018-06-30"
-H "Authorization: SharedAccessSignature sr=x&sig=x&se=x&skn=iothubowner"
雑記
ちなみに、この件を調べていたら、自分が書いた記事を見つけて「コマンド変えたくらいで発行されたToken変わるわけじゃないしなー」と思って、試すのが遅れました。
過去の私、ごめんなさい。
アウトプットって本当に大事ですね。
あと、偏見と先入観をもたず、記事を読みましょう。
以上。