如何改用容器级SAS获取CloudBlobContainer对象(解决连接串错误)
问题:使用容器级SAS获取Azure Blob容器引用时连接字符串无效
问题背景
原代码通过Blob存储端点+账户级SAS成功获取两个CloudBlobContainer对象引用,现需改为使用容器级SAS实现相同功能,但按照微软官方方案修改后,触发Invalid connection string(无效连接字符串)错误。
环境信息
- blobstorageConnection对象包含Blob存储端点、两个容器名称,以及新增的
container1Sas、container2Sas属性(对应容器级SAS令牌) - 使用的依赖:
<dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure-storage</artifactId> <version>8.6.6</version> </dependency>
- Java版本:1.8.0_362(无法升级)
原代码(账户级SAS实现)
CloudStorageAccount storage = null; try { this.BLOB_STORAGE_ENDPOINT = blobstorageConnection.getEndpoint(); String SAS = blobstorageConnection.getSas(); this.CONTAINER_1_NAME = blobstorageConnection.getContainer1Name(); this.CONTAINER_2_NAME = blobstorageConnection.getContainer2Name(); String SASBasedConnectionString = "BlobEndpoint=" + BLOB_STORAGE_ENDPOINT + ";SharedAccessSignature=" + SAS; storage = CloudStorageAccount.parse(SASBasedConnectionString); CloudBlobClient serviceClient = storage.createCloudBlobClient(); this.container1 = serviceClient.getContainerReference(CONTAINER_1_NAME); this.container2 = serviceClient.getContainerReference(CONTAINER_2_NAME); container1.createIfNotExists(); container2.createIfNotExists(); } catch (URISyntaxException | InvalidKeyException | StorageException e) { throw new RuntimeException(e); }
官方方案的错误表现
按照官方提供的修改方案执行后,在调用CloudStorageAccount.parse(SASBasedConnectionString)时抛出异常:
Exception in thread "main" java.lang.IllegalArgumentException: Invalid connection string. at com.microsoft.azure.storage.CloudStorageAccount.parse(CloudStorageAccount.java:290) at org.wso2.carbon.wum.ucreator.blobstorage.BlobStorageManager.<init>(BlobStorageManager.java:57)
正确修改方式
问题根源
Azure Storage SDK 8.6.6版本的CloudStorageAccount.parse方法不支持在连接字符串中添加ContainerName参数,官方方案的写法不适用于该旧版本SDK。
修改后的代码
直接通过容器的完整URL(Blob端点 + 容器名称 + 容器级SAS令牌)初始化CloudBlobContainer实例,无需通过CloudStorageAccount和CloudBlobClient中转:
try { this.BLOB_STORAGE_ENDPOINT = blobstorageConnection.getEndpoint(); this.CONTAINER_1_NAME = blobstorageConnection.getContainer1Name(); this.CONTAINER_2_NAME = blobstorageConnection.getContainer2Name(); String container1Sas = blobstorageConnection.getContainer1Sas(); String container2Sas = blobstorageConnection.getContainer2Sas(); // 构建容器1的完整URI,注意SAS令牌若已带?则去掉手动添加的? URI container1Uri = new URI(BLOB_STORAGE_ENDPOINT + "/" + CONTAINER_1_NAME + "?" + container1Sas); this.container1 = new CloudBlobContainer(container1Uri); container1.createIfNotExists(); // 构建容器2的完整URI URI container2Uri = new URI(BLOB_STORAGE_ENDPOINT + "/" + CONTAINER_2_NAME + "?" + container2Sas); this.container2 = new CloudBlobContainer(container2Uri); container2.createIfNotExists(); } catch (URISyntaxException | StorageException e) { throw new RuntimeException(e); }
注意事项
- 确保容器级SAS令牌不包含开头的
?,如果你的SAS令牌已经带有?,则URL拼接时删除代码中手动添加的? - 若SAS令牌没有包含创建容器的权限,需移除
createIfNotExists()调用,或调整SAS的权限配置
内容的提问来源于stack exchange,提问作者Pasan Kalansooriya
相关产品推荐
相关产品推荐

