Google API - Godaddy上的服务帐户C#

时间:2015-02-18 12:52:02

标签: c# google-api x509certificate2 service-accounts

我遇到了一个大问题。

我在ASP.NET中构建了一个MVC WebAPI,它使用谷歌API(服务帐户)写入谷歌电子表格。我可以很好地运行应用程序,也可以写入电子表格。但问题是,当我将它托管在godaddy的共享Windows服务器上时,它会给我一个错误。


  

[CryptographicException:

     

发生内部错误。

     

]
  System.Security.Cryptography.CryptographicException.ThrowCryptographicException(的Int32   hr)+33 System.Security.Cryptography.X509Certificates.X509Utils。

     

_LoadCertFromFile(String fileName,IntPtr password,UInt32 dwFlags,   Boolean persistKeySet,SafeCertContextHandle& pCertCtx)

     

0
  System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(字符串   fileName,Object password,X509KeyStorageFlags keyStorageFlags)+218
  System.Security.Cryptography.X509Certificates.X509Certificate.Import(字符串   fileName,String password,X509KeyStorageFlags keyStorageFlags)+33
  System.Security.Cryptography.X509Certificates.X509Certificate2.Import(字符串   fileName,String password,X509KeyStorageFlags keyStorageFlags)+33
  GAExampleMVC.GoogleAnalytics.GoogleAnalyticsService.GetStats()in   d:\ Aakash \ Thermax的\的WebAPI \ GAExampleMVC \ GAExampleMVC \ Google分析\ GoogleAnalytics.cs:50   GAExampleMVC.Controllers.HomeController.Index()in   d:\ Aakash \ Thermax的\的WebAPI \ GAExampleMVC \ GAExampleMVC \控制器\ HomeController.cs:16   lambda_method(Closure,ControllerBase,Object [])+62
  System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase   controller,Object []参数)+14
  System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext   controllerContext,IDictionary 2 parameters) +211
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2   参数)+27
  System.Web.Mvc<> c__DisplayClass15.b__12()   +55 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter)   filter,ActionExecutingContext preContext,Func 1 continuation) +253
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +21 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList
1个过滤器,ActionDescriptor actionDescriptor,   IDictionary`2参数)+189
  System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext   controllerContext,String actionName)+324
  System.Web.Mvc.Controller.ExecuteCore()+ 105


我只是不明白为什么它不适用于Godaddy,而相同的代码在localhost中运行良好。

我想这与我的代码无法访问的某个证书存储有关。

任何人都可以帮助我了解确切的问题以及如何解决它。

1 个答案:

答案 0 :(得分:0)

我知道这篇文章比较老,但我想我会根据我最近的经验提供答案,以防其他人遇到它。据我所知,实际问题是GoDaddy不允许在共享主机上更改App Pool身份。要解决问题的根源,必须为App Pool标识设置“加载用户配置文件”设置。这允许加载p12。但是,正如我所说,这不是共享主机平台的选择。所以,解决方法......

我对解决方案的灵感来自this post。我对Bouncy Castle没有经验,也没有时间学习,所以这就是我想出来的。

首先...使用开发者控制台获取Google提供的p12文件,并将其转换为pk8私钥。我使用OpenSSL来做到这一点。

openssl pkcs12 -in file.p12 -nocerts -out key.pem
openssl pkcs8 -in key.pem -topk8 -out p8key.pem

其次,将生成的pk8密钥保存在应用程序App_Data文件夹中。

第三,使用StreamReader从pk8文件中读取密钥,并使用.FromPrivateKey而不是.FromCertificate初始化ServiceAccountCredential。

Dim stReader As New System.IO.StreamReader _
(HostingEnvironment.ApplicationPhysicalPath & "[PathToPK8File].pk8")
        Dim aLine As String
        Dim keyfile As String
        While True
            aLine = stReader.ReadLine()
            If aLine Is Nothing Then
                keyfile = keyfile & vbCrLf
                Exit While
            Else
                keyfile = keyfile & aLine & " "
            End If
        End While

        Dim scopes As IList(Of String) = New List(Of String)()

        scopes.Add(CalendarService.Scope.CalendarReadonly)

        Dim credential As ServiceAccountCredential = New ServiceAccountCredential(
            New ServiceAccountCredential.Initializer(serviceEmail) With {
            .Scopes = scopes
            }.FromPrivateKey(keyfile)) // Use FromPrivateKey instead of FromCertificate

所有在生产服务器上正确加载。