通过查看 Azure Storage Java SDK,我发现 generateSharedAccessSignature 方法最终会调用如下:
public String generateSharedAccessSignature(
final SharedAccessBlobPolicy policy, final SharedAccessBlobHeaders headers,
final String groupPolicyIdentifier, final IPRange ipRange, final SharedAccessProtocols protocols)
throws InvalidKeyException, StorageException {
if (!StorageCredentialsHelper.canCredentialsSignRequest(this.blobServiceClient.getCredentials())) {
throw new IllegalArgumentException(SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY);
}
final String resourceName = this.getCanonicalName(true);
final String signature = SharedAccessSignatureHelper.generateSharedAccessSignatureHashForBlobAndFile(
policy, headers, groupPolicyIdentifier, resourceName, ipRange, protocols, this.blobServiceClient,
this.isSnapshot() ? Constants.QueryConstants.BLOB_SNAPSHOT_SERVICE : Constants.QueryConstants.BLOB_RESOURCE,
this.getSnapshotID());
final UriQueryBuilder builder = SharedAccessSignatureHelper.generateSharedAccessSignatureForBlobAndFile(
policy, headers, groupPolicyIdentifier,
this.isSnapshot() ? Constants.QueryConstants.BLOB_SNAPSHOT_SERVICE : Constants.QueryConstants.BLOB_RESOURCE,
ipRange, protocols, signature);
return builder.toString();
}
签名字符串是一个 Hmac256 字符串。StorageCredentialsHelper 中有一个方法可以计算它。
public static synchronized String computeHmac256(final StorageCredentials creds, final String value) throws InvalidKeyException {
if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) {
byte[] utf8Bytes = null;
try {
utf8Bytes = value.getBytes(Constants.UTF8_CHARSET);
}
catch (final UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
return Base64.encode(((StorageCredentialsAccountAndKey) creds).getHmac256().doFinal(utf8Bytes));
}
else {
return null;
}
}
在此方法中,需要 StorageCredentialsAccountAndKey。它是可用于签署数据的密钥。但是,由于您使用 MSI 作为身份验证,因此您使用的令牌实际上是 AAD 访问令牌,不能用于在此位置登录。您可以使用以下代码进行检查:
StorageCredentials credentials = blobClient.getCredentials();
System.out.println(credentials.toString(true));
所以,在 generateSharedAccessSignature 方法中,会抛出一个错误:
if (!StorageCredentialsHelper.canCredentialsSignRequest(this.blobServiceClient.getCredentials())) {
throw new IllegalArgumentException(SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY);
}
总之,如果您当前使用 MSI 作为身份验证,则无法生成 SharedAccessSignature。您可以将您的请求发布到Azure 存储用户语音。如果您的请求获得高票,开发人员团队可能会添加此功能。