使用Java SDK连接Azure Blob遇认证失败,请求排查原因
问题描述
使用Java SDK连接Azure Blob存储时,调用createIfNotExists()或create()方法持续触发认证错误,提示签名格式不正确。已尝试修改本地机器时区为GMT或Blob所在的eastus2时区,问题仍未解决。
代码示例
StorageCredentials storageCredentials = new StorageCredentialsAccountAndKey(getShareAccount(), Base64.encode(getShareKey().getBytes())); CloudStorageAccount storageAccount = new CloudStorageAccount(storageCredentials, true); CloudBlobClient c = storageAccount.createCloudBlobClient(); CloudBlobContainer container = c.getContainerReference(containerName); container.createIfNotExists();
错误信息
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
调用container.create()时的错误信息:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:....
Time:2024-02-09T09:16:26.4410074Z
解决方案
1. 修正存储密钥的编码逻辑
Azure存储账户的访问密钥本身就是Base64编码后的字符串,不需要再次执行Base64编码。重复编码会导致签名生成错误,直接使用原始密钥字符串即可:
StorageCredentials storageCredentials = new StorageCredentialsAccountAndKey(getShareAccount(), getShareKey());
2. 验证账户名称与密钥的正确性
- 确认
getShareAccount()返回的存储账户名称与Azure门户中的名称完全一致(区分大小写)。 - 检查
getShareKey()获取的是存储账户的访问密钥(可在Azure门户的「存储账户 > 安全+网络 > 访问密钥」中复制验证),而非连接字符串或SAS令牌。
3. 升级至最新版SDK
你当前使用的是旧版Azure Storage SDK(com.microsoft.azure.storage包),该版本已停止维护,存在签名算法兼容性问题。建议升级到最新的Azure Blob Storage SDK for Java(com.azure.storage.blob包),新版认证逻辑更稳定:
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder() .connectionString("你的存储账户连接字符串") .buildClient(); BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName); containerClient.createIfNotExists();
4. 确保本地时间与UTC同步
Azure存储要求请求时间与服务器UTC时间的误差不超过15分钟。即使修改了时区,仍需检查本地时间的准确性:
- Linux系统执行
date -u查看UTC时间,对比错误信息中的Time字段。 - Windows系统执行
w32tm /query /status检查时间同步状态,确保偏差在允许范围内。
内容的提问来源于stack exchange,提问作者radurbalau

