2017-03-25 15 views
0

私は、自分のポリシーが "不正な形式"であるにもかかわらず、PHPを使用してカスタムポリシーで署名付きCloudFront URLを作成する必要があります。ここ は、関数で生成された例ポリシーです:CloudFront "MalformedPolicy" error with signed URLs

{"Statement":{"Resource":"https://d15xojelh58w5d.cloudfront.net/memo/kwz/cvyhkfdqn5oz0z1dz5at4z4s1jsn.kwz","Condition":{"DateLessThan":{"AWS:EpochTime":1490463203},"IpAddress":{"AWS:SourceIp":"1.2.3.4/32"}}}} 

生成されたURL:

https://d15xojelh58w5d.cloudfront.net/memo/kwz/cvyhkfdqn5oz0z1dz5at4z4s1jsn.kwz?Policy=eyJTdGF0ZW1lbnQiOnsiUmVzb3VyY2UiOiJodHRwczovL2QxNXhvamVsaDU4dzVkLmNsb3VkZnJvbnQubmV0L21lbW8va3d6L2N2eWhrZmRxbjVvejB6MWR6NWF0NHo0czFqc24ua3d6IiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNDkwNDYzMjAzfSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjEuMi4zLjQvMzIifX19fQ__&Signature=MmBPtpipFLuNwaPliGLJajG4gJ7INwD0ptFdxPFYQP9CT-luq6W0SrAs9O9CqbJPHoukXwDzG~c88Rr5I2I9KP5QwD8MHpogGh~3SM3gBYm8ao0Zm7a5C9tWnBVRCtzuGrCrFstK-qLswWmqo6tNiOynSuFpvm9uDe3C8oWE2RzSZavEXoL35D3F8y98NeM0aOJe37EeSpdz3lrZZxei2TugoO-OmnApXa2YYJR2HiQ2l0t8paxcb3xyhCK1c1AR51uOpWLm63k~d0eNZJGo3x0Y6bx0GBqafdvV6jiUv6PbhiMC1ZcTxGnZhLmsz3~ONsEvaR1jyyOPt6y9Nos8yA__&Key-Pair-Id=APKAJ6RV6ACUX5M5IAOQ 

コード:

function cloudfront_sign($url, $expiry = null, $ipLock = true) { 
    $policy = array(
     'Statement' => array(
      'Resource' => $url, 
      'Condition' => array(), 
     ), 
    ); 

    if(!$expiry || $expiry <= time()) $expiry = 2147483647; // CloudFront *requires* an expiry date, so set to 03:14:07 UTC on Tuesday, 19 January 2038 if one is not provided 
    $policy['Statement']['Condition']['DateLessThan'] = array('AWS:EpochTime' => $expiry); 
    if($ipLock) $policy['Statement']['Condition']['IpAddress'] = array('AWS:SourceIp' => $_SERVER['REMOTE_ADDR'].'/32'); 

    $signer = new Aws\CloudFront\UrlSigner($_config['keyID'], $_config['keyPath']); 

    $jsonPolicy = json_encode($policy, JSON_UNESCAPED_SLASHES); 

    $url = $signer->getSignedUrl($url, null, $jsonPolicy); 

    return $url; 
} 
$url = kaeru_cloudfront_sign('https://d15xojelh58w5d.cloudfront.net/memo/kwz/cvyhkfdqn5oz0z1dz5at4z4s1jsn.kwz', 1490463203); 

答えて

1

「私は起こって正確に何を伝えることができますが、私ができますそれはあなたが(明らかに)使用しているSDKのバージョンのバグでない限り、なぜあなたに教えてください。

ポリシー文書は実際には不正な形式であり、署名もあります。

は実際に何か間違っているとは思われません。

64ビットを使って必ずしも8ビットクリーンではないトランスポートでバイナリデータを転送できるように、8ビットデータがオクテットごとに6ビットに拡張されているbase64に精通していると仮定します^ 6、6ビットの離散値の数)。

0-9A-Za-z必要なシンボルの10 + 26 + 26 = 62を構成し、次いで64に総シンボルをもたらすため+/があります、だけで終わりで出力のオクテットが存在し得るので2または4ビットの入力が符号化されている場合、「パディング」のための第65シンボル=は、入力データを表さない、未使用のビットが前のシンボルに存在することを示す。したがって、base64表現は常に0,1,2のいずれかで終了します。=シンボル。このため、base64でエンコードされた値は、末尾以外では決して=になることはありません。これは以下の点で重要であることが判明しました。間違ってそれらを扱う

シンボル+/=の選択肢があるため非常に多くのユーザーエージェント(ブラウザとHTTPクライアントライブラリ)によって引き起こされる曖昧で、URLのためにひどいです、それは、URLエスケープをしています(また、URLエンコードと呼ばれますまたはパーセント符号化)。

+が時々%20(スペース)と同等とみなされ、それは%2Bのようにエスケープのその他の回は... =は、クエリ文字列内のフィールドを区切るために使用されているため、一部のユーザーエージェントは%3Dとしてそれを脱出...と/%2Fとしてエスケープされることがあります。そのすべてが相互運用性の悪夢につながります。

(誤ったURLエスケープに関連するバグは少なくともありますが、これは修正が間に合わないほど長くなっていますが、誤った動作を予期するように作成されたコードがすべて破損するためです。 S3。しかし、これは手元の問題とは無関係です。)

CloudFrontの設計者はこれを巧妙に回避しました。

次のようCloudFrontのは3つの潜在的に問題の文字をtransliterates:

+ => - 
/=> _ 
= => ~ 

これがうまくいくの文字-_~はほぼ誤差などのURLでがちではありませんので。

しかし、どういうわけか、あなたのコードでは、この翻訳は間違っています。

&Signature=...~ONsEvaR1jyyOPt6y9Nos8yA__&Key-... 

これは間違いです。署名の真ん中にある~は、おそらく有効ではありません。上記のように、~=であり、これはbase64エンコーディングのエンドでのみ有効です。署名とポリシーの最後の__も間違っていて、実際には~~であるはずです。

?Policy=ey...X19fQ__&Signature= 

部分的に交換することで確認できます。ポリシーの最後にある__~~に変更すると、ポリシーに唯一問題があるように思われるため、Malformed Policyエラーが表示されなくなります。

残念ながら、ポリシーには~または-が含まれていないため、署名を有効にするためにどの文字の置換が必要であるかについて結論に至ることはできません。それは実際に動作するはずです。問題は、~_のみが入れ替えられているのか、3つすべて(-を含む)が間違っているのかわかりません。

最終的なURLを生成している実際のコードでは、ではなく、のJSONポリシー文書に問題があることが明らかです。

+0

実際、あなたは正しいです。最終的に、Aws \ CloudFront \ CloudFrontClient(ドキュメントの深いところに隠れているサンプルコードに基づいています)のgetSignedUrl関数を使用して、奇妙なことにうまく動作するようになりました。しかし、ありがとう! – jsa