0

Windows Azureを1.7からバージョン2に移行(ため息)していますが、古い認証方法でいくつかの問題が発生しています。次のコードを実行しようとすると(Azure SDKの古い実装で作業します)...

[...]

var policy = new SharedAccessBlobPolicy();
policy.SharedAccessStartTime = new DateTimeOffset(DateTime.UtcNow.AddMinutes(-5));
policy.SharedAccessExpiryTime = policy.SharedAccessStartTime.Value.AddMinutes(5);
policy.Permissions = SharedAccessBlobPermissions.Read;

var sas = blobContainer.GetSharedAccessSignature(policy)
var request = WebRequest.Create(string.Format("{0}/{1}{2}", containerUri, blobName, sas));
request.Method = "GET";
var headers = new NameValueCollection();
headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add(headers);
request.ContentLength = 0;

var response = (HttpWebResponse)request.GetResponse();

[...]

... GetResponse()メソッドは私に腹を立て、「サーバーはリクエストの認証に失敗しました。署名を含めてAuthorizationヘッダーの値が正しく形成されていることを確認してください。」というWebExceptionをスローします。

ResponseUriはhttp://127.0.0.1:10000/devstoreaccount1/testcontainer/testBlob?sv=2012-02-12&st=2013-01-22T09.52.27Z&se=2013-01-22T09.57.29Z&sr=c&sp=r&sig=WxFfIg9NxKodH7zGjKRym7RuXd61F5jlG6ILtG1UYPg%3D、私には問題ないように見えます。AccountKeyの問題だと思いましたが、Azureポータルから提供された正しいキーを使用して、実際のストレージで試してみると同じ問題が発生します。

新しいRESTAPIに対して実行するプロパティまたは新しい初期化はありますか?

更新:@Gaurav Mantriが彼の返信で開発したコンソールアプリケーションを試しましたが、それでも機能しませんでした。したがって、問題は私のマシンでのイタリア語のローカリゼーション、またはWindows 8に関連するいくつかの問題に依存している可能性があります(別の同僚のマシンでは、コンソールアプリケーションも機能せず、同じエラー403が禁止されています!GetResponse)。取得したURIは、ネット上で見つけたすべての例とは異なることに気づきました。そのため、開始時刻と有効期限は、(たとえば)2013-01-22T09.52.27Zではなくとして表示されます。2013-01-22T09%3A52%3A27Z

4

3 に答える 3

1

わかりました、どれが問題であるかがわかりました。

この行をコード (またはテスト初期化子) に追加するThread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;と、問題が解決します。

CultureInfo.InvariantCultureWindowsAzure.Storage ソースを見ると、サービスが署名を作成するときに、パラメーターとしてメソッドに渡すことなく、書式文字列 "yyyy-MM-ddTHH:mm:ssZ" が使用されますToString。ただし、イタリアの地域設定では、時間、分、秒の区切りはドットであり、米国では 2 ポイントです。そのため、私のローカル マシンとリモート マシンは 2 つの異なる署名を作成しましたが、一致させることができませんでした。

これをバグ (または問題) として報告します。すべての人が同じ地域設定を使用しているわけではないためです。

于 2013-01-23T15:08:22.460 に答える
0

GET 操作の場合、"x-ms-blob-type" 要求ヘッダーを追加する必要はありません。BLOB をアップロードする場合にのみ必要です。次のコード行を削除してから、もう一度お試しください:

var headers = new NameValueCollection();
headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add(headers);

更新: SAS URI を使用して BLOB を読み取るための完全なコードは次のとおりです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Net;
using System.IO;
namespace ConsoleApplication26
{
    class Program
    {
        static void Main(string[] args)
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
            CloudBlobContainer blobContainer = storageAccount.CreateCloudBlobClient().GetContainerReference("temp");
            //Create blob container.
            blobContainer.CreateIfNotExists();
            string blobContents = "Let's test SAS out :)";
            byte[] bytes = Encoding.UTF8.GetBytes(blobContents);

            string blobName = "sastest.txt";
            CloudBlockBlob blob = blobContainer.GetBlockBlobReference(blobName);
            //Upload blob
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                blob.UploadFromStream(ms);
            }
            //Get SAS Uri
            var sasUri = GetSasUrl(blobContainer, blobName);
            DownloadBlob(sasUri);

            Console.ReadLine();

        }

        static Uri GetSasUrl(CloudBlobContainer blobContainer, string blobName)
        {
            var policy = new SharedAccessBlobPolicy()
            {
                SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),
                SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(5),
                Permissions = SharedAccessBlobPermissions.Read,
            };

            var sas = blobContainer.GetSharedAccessSignature(policy);
            return new Uri(string.Format("{0}/{1}{2}", blobContainer.Uri, blobName, sas));
        }

        static void DownloadBlob(Uri sasUri)
        {
            var request = (HttpWebRequest)WebRequest.Create(sasUri);
            request.Method = "GET";
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                long responseContentLength = response.ContentLength;
                byte[] fetchedContents = new byte[(int) responseContentLength];
                using (var stream = response.GetResponseStream())
                {
                    stream.Read(fetchedContents, 0, fetchedContents.Length);
                }
                string blobContents = Encoding.UTF8.GetString(fetchedContents);
                Console.WriteLine("Blob Contents: " + blobContents);
            }
        }
    }
}
于 2013-01-22T11:56:58.640 に答える