【问题标题】:Azure Iot Hub create device API, IotHubUnauthorizedAccess;UnauthorizedAzure IoT Hub 创建设备 API,IotHubUnauthorizedAccess;Unauthorized
【发布时间】:2021-12-10 00:06:00
【问题描述】:

一段时间以来,我一直在尝试从 Android 手机创建一个 IoT Hub 设备,尽管遵循了我能找到的所有说明或教程,但我仍然得到:

{
"Message": "ErrorCode:IotHubUnauthorizedAccess;Unauthorized",
"ExceptionMessage": "Tracking ID:cc3e0c722b6040f89239c14c8bace4b9-G:0-TimeStamp:12/09/2021 23:29:46"

}

我尝试了几种不同的方式在 Android 代码中用 Java 创建 SharedAccessSignature:

    private static String GetSASToken(String resourceUri, String keyName, String key)
{
    long epoch = System.currentTimeMillis()/1000L;
    int week = 60*60*24*7;
    String expiry = Long.toString(epoch + week);
    Log.d(TAG, "GetSASToken: expiry: " + expiry);

    String sasToken = null;
    try {
        String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry;
        String signature = getHMAC256(key, stringToSign);
        sasToken = "SharedAccessSignature sr=" + URLEncoder.encode(resourceUri, "UTF-8") +"&sig=" +
                URLEncoder.encode(signature, "UTF-8") + "&se=" + expiry + "&skn=" + keyName;
    } catch (UnsupportedEncodingException e) {

        e.printStackTrace();
    }

    return sasToken;
}

public static String generateSasToken(String resourceUri, String key) throws Exception {
    // Token will expire in one hour
    long expiry = Instant.now().getEpochSecond() + 3600;

    String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry;

    byte[] decodedKey = Base64.getDecoder().decode(key);

    Mac sha256HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(decodedKey, "HmacSHA256");
    sha256HMAC.init(secretKey);
    Base64.Encoder encoder = Base64.getEncoder();

    String signature = new String(encoder.encode(
            sha256HMAC.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8))), StandardCharsets.UTF_8);

    String token = "SharedAccessSignature sr=" + URLEncoder.encode(resourceUri, "UTF-8")
            + "&sig=" + URLEncoder.encode(signature, StandardCharsets.UTF_8.name()) + "&se=" + expiry;

    return token;
}

然后按通常的方式调用:

            try{
            URL finalURL = new URL(stringUrl);

            urlConnection = (HttpsURLConnection)finalURL.openConnection();
            urlConnection.setReadTimeout(10000);
            urlConnection.setConnectTimeout(0);
            urlConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            urlConnection.setRequestProperty("Accept","application/json");
            urlConnection.setRequestProperty("Authorization",token2);
            urlConnection.setRequestMethod("PUT");
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            int responseCode = urlConnection.getResponseCode();
        }catch (MalformedURLException e) {
            e.printStackTrace();
            Log.d(TAG, "doInBackground: error 1 " + e.toString());
        }catch(UnknownHostException e){
            Log.d(TAG, "doInBackground: e: " + e);
        }
        catch(Exception e){
            Log.d(TAG, "doInBackground: error 2 " + e.toString());
        }
        finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
        return null;
    }

我的 Sas 令牌采用以下形式:

SharedAccessSignature sr=XXXXXXXXXXXXXXXX.azure-devices.net&sig=XXXXXXXXXXXXXXXXXXXXXXXB6%2BM6L0JR0UpgFxmvuX7g%3D&se=1639698883&skn=iothubowner

我在 Postman 中使用的 URL 是:

https://XXXXXXXXXX-westus2.azure-devices.net/devices/testDevice1?api-version=2020-03-13

授权标头设置为上述 SAS

我还使用 Python 创建了 SAS,以防编码出现问题。但是我所做的一切都是在点击同样的未经授权的访问消息,我开始拔头发了。

【问题讨论】:

  • 尝试查看错误是在您的 SAS 代码还是 API 调用中的一件事:使用 az cli 生成 SAS 令牌。您可以使用az iot hub generate-sas-token --hub-name {your-hub-name} 生成令牌。
  • 谢谢,不管我是通过 Postman 还是通过 Java 代码调用,仍然会出现同样的错误。

标签: azure azure-iot-hub shared-access-signatures


【解决方案1】:

以下屏幕 sn-p 显示了使用 REST POST 调用将遥测数据发送到 IoT 中心的示例:

出于测试目的,使用包含的Azure IoT Explorer 同时生成一个 SaS 令牌,请参见以下屏幕 sn-p:

更新:

以下屏幕 sn-p 显示了使用 REST PUT 请求创建 Azure IoT Hub 设备的示例:

上述请求的 sasToken 已由 document 中描述的 C# 代码根据 IoT Hub 共享访问策略生成iothubowner

string sasToken = generateSasToken("rk2019-iot.azure-devices.net", "****", "iothubowner");

【讨论】:

  • 谢谢,也试过了,错误至少改变了一点:"Message": "ErrorCode:InvalidProtocolVersion;BadRequest",
  • 屏幕截图显示了为设备创建 SAS。问题是关于使用 Service API 创建设备。
  • @MatthijsvanderVeer 你是对的,在这种情况下应该使用像设备资源管理器这样的工具来进行测试并生成 sasToken github.com/fsautomata/azure-iot-sdks/blob/master/tools/…
猜你喜欢
  • 2022-08-02
  • 2018-06-28
  • 2017-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-07
  • 2020-02-06
相关资源
最近更新 更多