C#+ Google Storage签名的URL:我们计算出的请求签名与您提供的签名不匹配

时间:2019-01-27 15:30:01

标签: c# google-cloud-platform google-cloud-storage

我刚刚创建了这个存储桶:mybucket231

运行以下C#代码以生成Signed-Url:

using (var stream = new FileStream(@"path/to/secret.json", FileMode.Open, FileAccess.Read))
{
    var cred = GoogleCredential.FromStream(stream)
                               .CreateScoped("https://www.googleapis.com/auth/devstorage.full_control")
                               .UnderlyingCredential as ServiceAccountCredential;

    var urlSigner = UrlSigner.FromServiceAccountCredential(cred);
    var publicLink = urlSigner.Sign("mybucket231", "file.test", TimeSpan.FromHours(1));
}

此代码生成具有full_control权限的签名URL。取回网址看起来像这样:

https://storage.googleapis.com/mybucket231/file.test?GoogleAccessId=new-storage-service-account@dotnet-core-cluster.iam.gserviceaccount.com&Expires=1548606014&Signature=HbL0ETXucaldz8jpoUDXUzYQu2YyhiMUh4Nfm69Y0sLyG3pvqbVvMMK1N8agywE8gW8s7kkInJCJuVGH%2FAHzd4LfeYo62iFK....FjnImQZq7fftv4TF5SpCPsVFnOGkSD6vOIpKqfJiswqGIERC9D7EJ%2B2DZ9JVMP7cEYjmAB9miemtD2eTVXu3FpBNbnDoxp112eTmu2F4TAckS0toX%2FmYk8GhOc9UnWH1iZ5VJ%2FKslFmRU0NFu4nxkDv7rk%2FRCvsOvvqrOqJT6cezE%2Bz%2FMONh%2FK5KfPs0ZnYslQwYNojhVR4sn5L8tVNst6gclFnA%3D%3D

现在,我要去Fiddler并尝试使用以下命令创建文件:

PUT https://storage.googleapis.com/mybucket231/file.test?GoogleAccessId=new-storage-service-account@secret.iam.gserviceaccount.com&Expires=1548606014&Signature=HbL0ETXucaldz8jpoUDXUzYQu2YyhiMUh4Nfm69Y0sLyG3pvqbVvMMK1N8agywE8gW8s7kkInJCJuVGH%2FAHzd4LfeYo62iFK....FjnImQZq7fftv4TF5SpCPsVFnOGkSD6vOIpKqfJiswqGIERC9D7EJ%2B2DZ9JVMP7cEYjmAB9miemtD2eTVXu3FpBNbnDoxp112eTmu2F4TAckS0toX%2FmYk8GhOc9UnWH1iZ5VJ%2FKslFmRU0NFu4nxkDv7rk%2FRCvsOvvqrOqJT6cezE%2Bz%2FMONh%2FK5KfPs0ZnYslQwYNojhVR4sn5L8tVNst6gclFnA%3D%3D

Headers:
User-Agent: Fiddler
Host: storage.googleapis.com
Content-Length: 3
content-type: text/plain

Body:
Hello world!

PUT消息使用此消息返回错误403(禁止):

<?xml version='1.0' encoding='UTF-8'?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message><StringToSign>PUT

plain/text
1548606014
/mybucket231/file.test</StringToSign>
</Error>

它说: SignatureDoesNotMatch 。但这很奇怪。我创建了这个文件,然后尝试动词GET-相同的签名确实起作用

如何?如何解决PUT动词?

注意:我的服务帐户(new-storage-service-account@secret.iam.gserviceaccount.com)是StorageAdmin。

1 个答案:

答案 0 :(得分:1)

发现了问题。实际上,这是两个问题:

  1. 您必须指定content-type标头。因此,添加
  2. 然后我遇到了另一个问题。允许content-type小写-这还不够!应该改为Content-Type

最终代码:

string url = urlSigner.Sign(
            "mybucket231",
            "file.test",
            TimeSpan.FromHours(1),
            HttpMethod.Put,
            contentHeaders: new Dictionary<string, IEnumerable<string>> {
                    { "Content-Type", new[] { "text/plain" } }
                }
            );