8

HttpWebRequestをS3に作成し、Dateヘッダーを次のように設定しようとしています。

「2012年7月16日月曜日01:16:18-0000」

これが私が試したことです:

string pattern = "ddd, dd MMM yyyy HH:mm:ss -0000";
request.Date = DateTime.ParseExact("Mon, 16 Jul 2012 01:16:18 -0000", pattern, null);

しかし、リクエストのヘッダーを見ると、次のようになります。

request.Headers.Get("Date");
// "Mon, 16 Jul 2012 07:16:18 GMT"

これがリクエストの403の理由かもしれないと私は信じています。AWSエラードキュメントには次のように記載されています:

403Forbidden-リクエスト時間とサーバーの時間の差が大きすぎます。

この日付を整理するための提案をいただければ幸いです。ありがとう!

4

4 に答える 4

15

明確にすることがいくつかあります:

  • 日付パターンが正しくありません。

  • HttpWebRequestrequest.Dateヘッダーは、.NET Framework 4でのみ変更できます。ドキュメントによると、名前空間は常にこのヘッダーをGMT(UTC)形式System.Netを使用して標準形式で書き込みます。だから、あなたが望むようにあなたの日付をフォーマットするためにあなたができることは何でも、うまくいきません!

  • 他の.NETFrameworkバージョンでは、独自の日付と形式を設定するために一種のハックを使用しない限り、正しいGMT(UTC)形式で実際の日付を使用するため、HttpWebRequestヘッダーを変更できませんrequest.Date(以下を参照)。


問題の解決策(テスト済みで機能中):

あなたの輸入品:

using System.Net;
using System.Reflection;

今日の日付を次の形式で取得します:2012年7月16日月曜日01:16:18 -0000

string today = String.Format("{0:ddd,' 'dd' 'MMM' 'yyyy' 'HH':'mm':'ss' 'K}", DateTime.Now);

ここで注意が必要です。これを行うことで、HttpWebRequestの日付ヘッダーをハックできます。

(もうやらrequest.Date = something;ないで、次のものに置き換えてください)

MethodInfo priMethod = request.Headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
priMethod.Invoke(request.Headers, new[] { "Date", today });

リクエストから日付を取得します(テストするためだけに):

// "myDate" will output the same date as the first moment: 
// Mon, 16 Jul 2012 01:16:18 -0000
// As you can see, you will never get this again:
// Mon, 16 Jul 2012 07:16:18 GMT
string myDate = request.Headers.Get("Date");

この時点で、独自の形式と日付の値をHttpWebRequestの日付ヘッダーに正常に設定できました。

お役に立てれば :-)

于 2012-07-16T04:22:35.323 に答える
1

HttpWebRequestは、それ自体で日付を適切にフォーマットします。あなたの問題はあなたが有効な現在の日付を提出しなければならないということです。コンピューターの時計が正確であることを確認してから、タイムゾーンとUTCおよびGMTの問題に関して適切な日付を送信していることを確認する必要があります...

両方を試してください:

request.Date = DateTime.Now;
request.Date = DateTime.UtcNow;

そのうちの1つが機能する必要があります(HttpWebRequestが適切に実装されている場合は両方が機能するはずです)。

それが機能しない場合は、フィドラーを使用して何が起こっているかを確認し、機能するまで手動でリクエストを修正します

于 2012-07-16T02:01:29.173 に答える
0

AuthorizationヘッダーのDateヘッダーを機能するように設定するとします。

Amazonは、Dateの代わりに使用される別のカスタムヘッダーを提供しています(提供されている場合)。Dateヘッダーを設定できない場合は、代わりにカスタムヘッダーx-amz-dateを使用できます。

こちらがAmazonのドキュメントへのリンクです

于 2013-05-17T18:13:36.827 に答える
-1

「X-Amz-Date」ヘッダーを使用する必要があります。

public void GetObject(string AccessKeyID, string SecretKey){           
        /*objectKey = folder/folder/filename.zzz*/
        var url = "http://somehost/bucket/objectkey"

        HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
        /*Fiddler proxy*/
        /*request.Proxy = new WebProxy("http://127.0.0.1:8888");*/

        request.Headers.Add("X-Amz-Date",String.Format("{0:ddd,' 'dd' 'MMM' 'yyyy' 'HH':'mm':'ss' 'K}", DateTime.Now));
        request.Headers.Add("Authorization", $"AWS {AccessKeyID}:{SignAuthorizationString(request, SecretKey)}");

        WebResponse response = request.GetResponse();
        }
private string SignAuthorizationString(HttpWebRequest request, string SecretKey){
        //TODO: DOCS - http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html

        string canonicalizedResource = request.RequestUri.PathAndQuery;
        string canonicalizedAmzHeaders  = ComposeSignatureAmzHeadersForSigning(request);
        string stringToSign = request.Method + "\n"
                              + request.Headers.Get("Content-MD5") + "\n"
                              + request.ContentType + "\n"
                              + request.Headers.Get("Date") + "\n" /*Here the date will be blank*/
                              + canonicalizedAmzHeaders + canonicalizedResource;

        return GetSignedMessage(SecretKey, stringToSign);
        }
 private string ComposeSignatureAmzHeadersForSigning(HttpWebRequest request){
        SortedDictionary<string, string> headersDictionary = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        foreach (string _key in request.Headers.Keys)
        {
            key = _key.ToLower(); 
            if (key.StartsWith("x-amz"))
            {
                if ("x-amz-meta-reviewedby".Equals(key))
                {
                    if (headersDictionary.ContainsKey(key))
                        headersDictionary[key] = headersDictionary[key] + "," + request.Headers[key];
                    else
                        headersDictionary[key] = request.Headers[key];
                }
                else
                    headersDictionary[key] = request.Headers.Get(key);
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        foreach (var pair in headersDictionary)
        {
            stringBuilder.Append(pair.Key)
                .Append(":")
                .Append(pair.Value)
                .Append("\n");

        }
        return stringBuilder.ToString();
        }
private static string GetSignedMessage(string key, string message){
        var crypt = HMACSHA1.Create();
        crypt.Key = Encoding.ASCII.GetBytes(key);
        crypt.ComputeHash(Encoding.UTF8.GetBytes(message));

        return Convert.ToBase64String(crypt.Hash);
        }
于 2016-09-14T09:15:00.300 に答える