【发布时间】:2019-05-08 06:32:00
【问题描述】:
尝试生成 SAS 令牌以访问存储帐户中的某些文件。我正在使用此处列出的方法:
https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token
现在,我遇到的问题是,我一辈子都无法让 sasToken 字符串工作。如果我通过门户(存储帐户中的共享访问签名)生成令牌,我可以使用提供的令牌通过 URL 访问这些文件。
但是,我还不能使用上面链接的方法通过 Java 以编程方式生成 SAS 令牌。我认为我的问题是正在加密的 StringToSign。在构造要加密的字符串时,我一直在关注这个例子:
https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
我所有的努力都导致了:
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
或
<AuthenticationErrorDetail>Signature did not match. String to sign used was <insert string details here>
查看 Portal 生成的适合我的 sasToken:
?sv=2017-11-09&ss=f&srt=o&sp=r&se=2018-12-06T22:15:20Z&st=2018-12-06T14:15:20Z&spr=https&sig=%2Bi1TWv5D80U%2BoaIeoBh1wjaO1p4xVFYz%3nRZt%2Fzwi p>
看来我需要这样的字符串:
String stringToSign = accountName + "\n" +
"r\n" +
"f\n" +
"o\n" +
URLEncoder.encode(start, "UTF-8") + "\n" +
URLEncoder.encode(expiry, "UTF-8") + "\n" +
"\n" +
"https\n" +
azureApiVersion;
其中 accountName 是 Azure 的存储帐户名称,start/expiry 是开始和到期字符串(即 2018-12-06T22:15:20Z),azureApiVersion 是“2017-11-09”。
然后我尝试在构造字符串后返回令牌,如下所示:
String signature = getHMAC256(key, stringToSign);
sasToken = "sv=" + azureApiVersion +
"&ss=f" +
"&srt=o" +
"&sp=r" +
"&se=" +URLEncoder.encode(expiry, "UTF-8") +
"&st=" + URLEncoder.encode(start, "UTF-8") +
"&spr=https" +
"&sig=" + URLEncoder.encode(signature, "UTF-8");
我也尝试了 URL 编码,而不是 URL 编码开始/到期日期,以防万一搞砸了。我错过了什么?
【问题讨论】:
-
您使用的密钥的值是多少?是你从portal得到的字符串还是base64解码账户密钥字符串得到的字节数组?
-
我的密钥的值是 Azure 中存储帐户上的访问密钥之一。
-
我相信问题出在您的
getHMAC256方法中。我查找了它的代码,它只是从字符串值中获取字节。实际上,您需要对密钥字符串进行 base64 解码并在此方法中使用该字节数组。 -
好的,我尝试更改基本 getHMAC256 方法以使用: SecretKeySpec secret_key = new SecretKeySpec(Base64.getDecoder().decode(key), "HmacSHA256");不幸的是,收到了“签名不匹配。使用的签名字符串是
”消息。 -
@seanDematic 我遇到了同样的错误?你解决了吗?
标签: java rest azure azure-storage