我一直在跟踪
latest writeup from Microsoft
为了生成一个帐户级的共享访问签名(SAS),以便与Azure存储服务(特别是Blob)一起使用。
每次我表演
PUT
请求我的blob服务,我收到
403
响应,带有消息:
服务器无法对请求进行身份验证。确保
授权头的格式正确,包括签名。
这是我生成签名的功能:
use MicrosoftAzure\Storage\Common\Internal\StorageServiceSettings;
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
public function generateUploadLink($container, $folder, $filename)
{
# get account settings
$settings = StorageServiceSettings::createFromConnectionString(AZURE_BLOB);
$accountName = $settings->getName();
$accountKey = $settings->getKey();
# define start and expire datetime stamps (ISO 8601)
$startTime = (new DateTime('GMT'))->modify('-2 days')->format('Y-m-d\TH:i:s\Z');
$expireTime = (new DateTime('GMT'))->modify('+2 days')->format('Y-m-d\TH:i:s\Z');
$parameters = [];
$parameters[] = $accountName; # account name
$parameters[] = 'wac'; # permissions
$parameters[] = 'b'; # service
$parameters[] = 'sco'; # resource type
$parameters[] = $startTime; # start time
$parameters[] = $expireTime; # expire time
$parameters[] = ''; # accepted ip's
$parameters[] = 'https,http'; # accepted protocol
$parameters[] = '2018-03-28'; # latest microsoft api version
# implode the parameters into a string
$stringToSign = utf8_encode(implode("\n", $parameters));
# decode the account key from base64
$decodedAccountKey = base64_decode($accountKey);
# create the signature with hmac sha256
$signature = hash_hmac("sha256", $stringToSign, $decodedAccountKey, true);
# encode the signature as base64
$sig = urlencode(base64_encode($signature));
# construct the sas (shared access signature)
$sas = "sv=2018-03-28&ss=b&srt=sco&sp=wac&se={$expireTime}&st={$startTime}&spr=https,http&sig={$sig}";
# create client
$blobClient = BlobRestProxy::createBlobService(AZURE_BLOB);
# generate upload link
$blobUrlWithSAS = sprintf('%s%s?%s', (string)$blobClient->getPsrPrimaryUri(), "{$container}/{$folder}/{$filename}", $sas);
# return upload link
return $blobUrlWithSAS;
}
我输出的一个示例,如下所示--当
放
请求此URL时失败,并显示上述错误消息。
https://batman.blob.core.windows.net/payroll-enroll/2019/test.txt?sv=2018-03-28&ss=b&srt=sco&sp=wac&se=2019-02-04T03:44:51Z&st=2019-01-31T03:44:51Z&spr=https,http&sig=ox7RdKGTKRYvGz2u9ScFv4TP4ZfduKxFhYdpvJKjE4A%3D
相比之下,如果我直接从Azure门户生成一个帐户级共享访问签名,那么在
放
请求此URL,它成功。
https://batman.blob.core.windows.net/payroll-enroll/2019/test.txt?sv=2018-03-28&ss=b&srt=sco&sp=wac&se=2019-02-02T16:29:17Z&st=2019-02-02T08:29:17Z&spr=https,http&sig=omPc4ZwEdefDoHKqA4TqVOm3NUW%2BcKcNqTuD1hq94VU%3D
除了起止时间外,我看不出两者有什么不同。除此之外,我还将注意到我已经尝试使用
azure-storage-php
结果相同的包(
无法验证请求
)
我已确认并或尝试以下事项:
-
$accountName
和
$accountKey
正在返回正确的值,与通过Azure门户看到的值相比
-
尝试每一个
now
,
UTC
和
GMT
作为参数
DateTime()
-
在每一侧提供足够的填充(2天),以确保它不是时间差问题,正如我在堆栈上读到的其他问题中经常提到的那样。
-
应用的通配符(
*
)我的存储帐户的CORS设置
ALLOWED METHODS
,
ALLOWED ORIGINS
,
ALLOWED HEADERS
和
EXPOSED HEADERS
-
残疾人
Secure transfer required
(允许两者兼而有之)
http
和
https
)
我被难住了。
我的问题
:构建SAS时我做错了什么?为什么我继续收到与身份验证相关的请求失败?