问题描述
我偶尔会遇到在服务器上生成的 Azure 存储 SAS 令牌的问题。我没有为开始时间设置任何内容,因为建议这样做以避免时钟偏差问题,并且我将到期时间设置为 DateTime.UtcNow
后 1 小时。有时,SAS 令牌不起作用,我猜这可能与时钟偏差问题有关。这是我最近收到的两个错误:
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server Failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:cb371f2b-801e-0063-16a1-08d06f000000 Time:2021-02-21T22:35:53.9832140Z</Message>
<AuthenticationErrorDetail>Signed expiry time [Sun,21 Feb 2021 20:39:40 GMT] must be after signed start time [Sun,21 Feb 2021 22:35:53 GMT]</AuthenticationErrorDetail>
</Error>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server Failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:8818c581-401e-0058-6477-08717d000000 Time:2021-02-21T17:35:37.1284611Z</Message>
<AuthenticationErrorDetail>Signature not valid in the specified time frame: Start [Sat,20 Feb 2021 00:15:01 GMT] - Expiry [Sat,20 Feb 2021 01:30:01 GMT] - Current [Sun,21 Feb 2021 17:35:37 GMT]</AuthenticationErrorDetail>
</Error>
这就是我生成令牌的方式:
var blobSasBuilder = new BlobSasBuilder
{
BlobContainerName = containerName,BlobName = fileName,Resource = "b",ExpiresOn = DateTime.UtcNow.AddHours(1),Protocol = SasProtocol.Https
};
我该如何解决这个问题?根据上面的错误,貌似我是在token过期后尝试访问这个资源的,但实际上我是在token生成并发送给客户端后立即尝试访问的。正如我所说,这种情况并不经常发生,但它是一个反复出现的问题。
再想一想,我想知道这是否是 v12 SDK 的错误。
解决方法
根据报错,开始时间晚于你的过期时间和当前时间。请将开始时间设置为至少过去 15 分钟。
例如
我使用 Net SDK Azure.Storage.Blobs
// Creates a client to the BlobService using the connection string.
var blobServiceClient = new BlobServiceClient(storageConnectionString);
// Gets a reference to the container.
var blobContainerClient = blobServiceClient.GetBlobContainerClient(<ContainerName>);
// Gets a reference to the blob in the container
BlobClient blobClient = containerClient.GetBlobClient(<BlobName>);
// Defines the resource being accessed and for how long the access is allowed.
var blobSasBuilder = new BlobSasBuilder
{
StartsOn = DateTime.UtcNow.Subtract(-15),ExpiresOn = DateTime.UtcNow.AddHours(1),BlobContainerName = <ContainerName>,BlobName = <BlobName>,};
// Defines the type of permission.
blobSasBuilder.SetPermissions(BlobSasPermissions.Write);
// Builds an instance of StorageSharedKeyCredential
var storageSharedKeyCredential = new StorageSharedKeyCredential(<AccountName>,<AccountKey>);
// Builds the Sas URI.
var sasQueryParameters = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential);
,
生成 SAS 的代码必须在正确设置日期、时间和时区的机器上运行。
两种情况的错误消息略有不同。 第一个错误:是说签名到期时间是错误时间之前的~1h:56m,这怎么可能?也许 SAS 到期时间设置为过早的值,我的意思是几乎提前 2 小时而不是提前 15 分钟?或者 SAS 开始时间很可能大于 SAS 结束时间?
第二个错误:错误的时间是2月21日,但是SAS在2月20日到期,再次,看起来SAS时间已经到期,但这次是35小时以上而不是15分钟。
也许运行生成 SAS 的代码的机器在时间上有一些问题?这可以通过定期(例如每分钟一次)轮询该机器的时间并比较结果来检查。