在C#/ Mono中,无法与谷歌云存储通信

时间:2016-04-04 20:31:34

标签: c# .net mono google-cloud-storage

我现在正在开发一个通过Mono在Linux实例上运行的C#应用​​程序。它需要在处理完图像后将图像存储在Google云端存储中。

我有auth凭据设置,.NET客户端库能够设置StorageService对象(即找到JSON文件并验证所有内容)。当我尝试上传时,什么都没发生。所以在我的SetupConnection()函数中,我试图查询我项目中的单个存储桶。我收到了这个错误:

Unhandled Exception:
System.Net.WebException: Error writing request: The authentication or decryption has failed.
  at System.Net.WebConnectionStream.WriteHeaders () [0x00000] in <filename unknown>:0 
  at System.Net.WebConnectionStream.SetHeaders (System.Byte[] buffer) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Net.WebConnectionStream:SetHeaders (byte[])
  at System.Net.HttpWebRequest.SendRequestHeaders (Boolean propagate_error) [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Http.ConfigurableMessageHandler+<SendAsync>d__43.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.Requests.TokenRequestExtenstions+<ExecuteAsync>d__0.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[Google.Apis.Auth.OAuth2.Responses.TokenResponse].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceAccountCredential+<RequestAccessTokenAsync>d__19.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Boolean].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceCredential+<GetAccessTokenForRequestAsync>d__23.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.String].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceAccountCredential+<GetAccessTokenForRequestAsync>d__20.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.String].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceCredential+<InterceptAsync>d__21.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Http.ConfigurableMessageHandler+<SendAsync>d__43.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Requests.ClientServiceRequest`1+<ExecuteUnparsedAsync>d__26[Google.Apis.Storage.v1.Data.Buckets].MoveNext () [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.WebException: Error writing request: The authentication or decryption has failed.
  at System.Net.WebConnectionStream.WriteHeaders () [0x00000] in <filename unknown>:0 
  at System.Net.WebConnectionStream.SetHeaders (System.Byte[] buffer) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Net.WebConnectionStream:SetHeaders (byte[])
  at System.Net.HttpWebRequest.SendRequestHeaders (Boolean propagate_error) [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Http.ConfigurableMessageHandler+<SendAsync>d__43.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.Requests.TokenRequestExtenstions+<ExecuteAsync>d__0.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[Google.Apis.Auth.OAuth2.Responses.TokenResponse].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceAccountCredential+<RequestAccessTokenAsync>d__19.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Boolean].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceCredential+<GetAccessTokenForRequestAsync>d__23.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.String].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceAccountCredential+<GetAccessTokenForRequestAsync>d__20.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.String].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Auth.OAuth2.ServiceCredential+<InterceptAsync>d__21.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Http.ConfigurableMessageHandler+<SendAsync>d__43.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00000] in <filename unknown>:0 
  at Google.Apis.Requests.ClientServiceRequest`1+<ExecuteUnparsedAsync>d__26[Google.Apis.Storage.v1.Data.Buckets].MoveNext () [0x00000] in <filename unknown>:0 

这是我的设置代码:

public static void SetupGCSConnection()
{
    var credentials = Google.Apis.Auth.OAuth2.GoogleCredential.GetApplicationDefaultAsync().Result;

    if (credentials.IsCreateScopedRequired)
        credentials = credentials.CreateScoped(new[] { StorageService.Scope.DevstorageFullControl });

    var serviceInitializer = new BaseClientService.Initializer()
    {
        ApplicationName = "MyApp",
        HttpClientInitializer = credentials
    };

    storage = new StorageService(serviceInitializer);

    // Error is thrown here
    var buckets = storage.Buckets.List(Config.GoogleProjectID).Execute();
    foreach (var b in buckets.Items) {
        Console.WriteLine(b.ToString());
    }
}

我以前能够让C#与GCS交谈,但那是我在Windows环境中使用Microsoft的.NET vm工作的时候。我之前做了一些研究,Mono处理CA与Microsoft的VM之间的关系可能存在一些问题。

2 个答案:

答案 0 :(得分:0)

您的问题通常来自未更新的根证书。

按照说明here更新根证书。

如果这没有帮助,那么您可以将代理设置为

ServicePointManager.ServerCertificateValidationCallback

并接受所有证书。如果可行,那么您就知道问题出在证书验证上,您可以尝试其他解决方案。 (我绝不会建议使用回调来接受生产中的所有证书,只是用它来调试你的问题。)

答案 1 :(得分:0)

我解决了这个问题。

我使用的是Ubuntu附带的默认Mono版本,它已经过时了。我转而使用官方的Mono存储库: http://www.mono-project.com/docs/getting-started/install/linux/

然后安装了ca-certificates-mono包。 (这里有更多细节:http://www.mono-project.com/docs/faq/security/

感谢Lex Li的帮助。