一段时间以来,我一直在尝试从 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
将 Authorization 标头设置为上述 SAS
我还使用 Python 来创建 SAS,以防编码出现问题。但是我所做的一切都是在点击同样的未经授权的访问消息,我开始把头发拉出来。