Azure 存储 table REST Api 调用 - 无效 Header
Azure storage table REST Api call - Invalid Header
我正在尝试调用 REST API 来查看 Azure 存储 table 的内容。
希望我已经正确地形成了 Authorization header 值并且我得到了以下错误。请纠正我在以下请求中遗漏的地方(来自 REST 客户端应用程序)。
{
"method": "GET",
"transformRequest": [
null
],
"transformResponse": [
null
],
"url": "https://#####.table.core.windows.net/testDB",
"headers": {
"x-ms-date": "Thu, 28 Jun 2018 08:39:05 GMT",
"x-ms-version": "2018-06-28",
"Accept": "application/json;odata=nometadata",
"Authorization": "SharedKeyLite #####:########"
},
"data": "",
"timeout": {}
}
这是我的回复Headers:
{
"x-ms-request-id": "3fc23b14-2002-0037-04bc-0e9e56000000",
"date": "Thu, 28 Jun 2018 08:46:39 GMT",
"server": "Microsoft-HTTPAPI/2.0",
"content-length": "371",
"content-type": "application/xml",
"status": 400
}
和回应Body
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>InvalidHeaderValue</code>
<message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.
RequestId:3fc23b14-2002-0037-04bc-0e9e56000000
Time:2018-06-28T08:46:40.1148690Z</message>
</error>
这里是JAVA代码,我用来生成SignatureString
private void printHash()
{
// https://mytestaccount.table.core.windows.net/testDB: this is the url form Azure portal displaying next to table
String secret = "I Updated my key here";
// Date for string to sign
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = sdf.format(calendar.getTime());
// canonicalizedResource, such as "/testaccount1/Tables"
String canonicalizedResource = "/testDB";
String stringToSign = date + "\n" + canonicalizedResource;
System.out.println(stringToSign);
// HMAC-SHA@%^
Mac sha256HMAC = null;
try {
sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256HMAC.init(secretKey);
String hash = Base64.encodeToString(sha256HMAC.doFinal(stringToSign.getBytes()), Base64.DEFAULT);
System.out.println(hash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
四点修正:
- x-ms-version 如果您想要获取
application/json;odata=nometadata
的内容,则不是可选的。 x-ms-version 应明确设置为 2013-08-15
或更高版本(最新为 2018-03-28) to support this format. See Json format in table service.
- 日期格式应为
EEE, dd MMM yyyy HH:mm:ss 'GMT'
。两位数字表示日。
- canonicalizedResource 应该是
storageAccountName\tableName
就像您的代码备注一样。
- 要生成SecretKeySpec,
SecretKeySpec secretKey = new SecretKeySpec(Base64.decode(secret), "HmacSHA256");
因为secret是用Base64编码的。
我正在尝试调用 REST API 来查看 Azure 存储 table 的内容。 希望我已经正确地形成了 Authorization header 值并且我得到了以下错误。请纠正我在以下请求中遗漏的地方(来自 REST 客户端应用程序)。
{
"method": "GET",
"transformRequest": [
null
],
"transformResponse": [
null
],
"url": "https://#####.table.core.windows.net/testDB",
"headers": {
"x-ms-date": "Thu, 28 Jun 2018 08:39:05 GMT",
"x-ms-version": "2018-06-28",
"Accept": "application/json;odata=nometadata",
"Authorization": "SharedKeyLite #####:########"
},
"data": "",
"timeout": {}
}
这是我的回复Headers:
{
"x-ms-request-id": "3fc23b14-2002-0037-04bc-0e9e56000000",
"date": "Thu, 28 Jun 2018 08:46:39 GMT",
"server": "Microsoft-HTTPAPI/2.0",
"content-length": "371",
"content-type": "application/xml",
"status": 400
}
和回应Body
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>InvalidHeaderValue</code>
<message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.
RequestId:3fc23b14-2002-0037-04bc-0e9e56000000
Time:2018-06-28T08:46:40.1148690Z</message>
</error>
这里是JAVA代码,我用来生成SignatureString
private void printHash()
{
// https://mytestaccount.table.core.windows.net/testDB: this is the url form Azure portal displaying next to table
String secret = "I Updated my key here";
// Date for string to sign
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = sdf.format(calendar.getTime());
// canonicalizedResource, such as "/testaccount1/Tables"
String canonicalizedResource = "/testDB";
String stringToSign = date + "\n" + canonicalizedResource;
System.out.println(stringToSign);
// HMAC-SHA@%^
Mac sha256HMAC = null;
try {
sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256HMAC.init(secretKey);
String hash = Base64.encodeToString(sha256HMAC.doFinal(stringToSign.getBytes()), Base64.DEFAULT);
System.out.println(hash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
四点修正:
- x-ms-version 如果您想要获取
application/json;odata=nometadata
的内容,则不是可选的。 x-ms-version 应明确设置为2013-08-15
或更高版本(最新为 2018-03-28) to support this format. See Json format in table service. - 日期格式应为
EEE, dd MMM yyyy HH:mm:ss 'GMT'
。两位数字表示日。 - canonicalizedResource 应该是
storageAccountName\tableName
就像您的代码备注一样。 - 要生成SecretKeySpec,
SecretKeySpec secretKey = new SecretKeySpec(Base64.decode(secret), "HmacSHA256");
因为secret是用Base64编码的。