4

共有アクセス署名をStorage2.0で機能させるのに問題があります。

私はコードを使用します:

if (blob.Exists())
{
    var expires = DateTime.UtcNow.AddMinutes(30);
    var sas = blob.GetSharedAccessSignature(new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy
    {
        Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Read,
        SharedAccessExpiryTime = expires
    });
    url = string.Concat(blob.Uri.AbsoluteUri, sas);
}
return url;

しかし、セッションをデバッグしてURLをブラウザーに貼り付けると、エラーが発生します。

<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:c1a1dd2b-bf4a-4a6b-bab2-ab1cb9363d27 Time:2012-11-19T14:41:51.1254531Z
  </Message>
  <AuthenticationErrorDetail>
Signature did not match. String to sign used was r 2012-11-19T15:11:36Z /container/path/1356/pic.jpg 2012-02-12
  </AuthenticationErrorDetail>
</Error>

誰か助けてもらえますか?

更新:結果のURLは次のようになります: https ://storageaccountname.blob.core.windows.net/container/path/1356/pic.jpg?sv = 2012-02-12&se = 2012-11-19T19%3A25%3A32Z&sr = b&sp = r&sig = s6QIdwAGY4xC8fs4L9pK8hAGIY%2F8x58aqBcFbejYPdM%3D

4

2 に答える 2

5

同じエラーが発生します。このコードは、2.0にアップデートする前は機能していました。

var sharedAccessPolicy = new SharedAccessBlobPolicy
{
  SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-10),
  SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(30),
  Permissions = SharedAccessBlobPermissions.Read
};
var sharedAccessSignature = _blockblob.GetSharedAccessSignature(sharedAccessPolicy);
return _blockblob.Uri.AbsoluteUri + sharedAccessSignature;

私はURIを取得します:

http://127.0.0.1:10000/devstoreaccount1/original/c04d2a1c-980b-42c5-b76e-b71185f027b6.jpg?sv=2012-02-12&st=2012-11-20T08%3A30%3A24Z&se=2012-11-20T09%3A10%3A24Z&sr=b&sp=r&sig=9%2BVg6mSGqyrfr5rPlNJ6GSv%2BHN3J9k%2FWFRLYmx3xCvQ%3D

更新、解決済み:

上記のコードには、_blockBlobがあります。これは、建設業者に設定されました

var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
CloudBlockBlob _blockblob = container.GetBlockBlobReference(fileName);

最後の行を(clausndkによって提案されたように)次のように変更します

ICloudBlob _test = container.GetBlobReferenceFromServer(fileName);

_testでGetSharedAccessSignatureを呼び出すと、異なる(有効な)署名が生成されるため、問題が解決されます。

Azureストレージのソースコードを確認し、アプリケーションでデバッガーを使用すると、問題の原因が見つかりました。私のコードには、末尾にスラッシュ(original /)が付いたcontainerNameがあります。GetSharedAccessSignatureの場合を除いて、これは問題ではありません。ここで、余分なスラッシュがcanonicalNameを台無しにし(2つのスラッシュを与えるコードに1つのスラッシュが追加されます)、これにより署名が無効になります。GetBlobReferenceFromServerが機能する理由は、サーバーに(REST APIを介して)blobを要求し、結果のCloudBlockBlobでスラッシュが削除されるためです。

私のコードでは、末尾のスラッシュを削除しましたが、コンテナー名に.Trim('/')を使用するSandrinoDiMattiaのソリューションも機能します。これは、余分なサーバー呼び出しが発生するため、GetBlobReferenceFromServerを使用するよりも優先されると思います。

うまくいけば、CloudBlockBlobBaseでのGetCanonicalNameの実装は、将来的に末尾のスラッシュを処理するように変更されます(これについては、GitHubで問題を作成しました)が、今のところ、この「回避策」は機能します。

于 2012-11-20T09:21:27.567 に答える
1

次のコードを試していただけますか?

var pathToMyBlob = "/path/1356/pic.jpg";
var blob = container.GetBlockBlobReference(pathToMyBlob.TrimStart('/'));

var expires = DateTime.UtcNow.AddMinutes(30);
var sas = blob.GetSharedAccessSignature(new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy
{
    Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Read,
    SharedAccessExpiryTime = expires
});

2行目、特にTrimStartの呼び出しを見てください。パスがスラッシュで始まっているファイルのBLOB参照を取得しようとすると、問題を再現できました。スラッシュを削除することにより、問題が修正されました。それで:

  • /path/1356/pic.jpg>機能しません
  • path / 1356/pic.jpg>作品
于 2012-11-20T12:26:41.727 に答える