【问题标题】:Google Calendar API and shared hosting issueGoogle Calendar API 和共享主机问题
【发布时间】:2016-09-23 12:18:13
【问题描述】:

我正在尝试在需要编辑功能的网页中使用公共 Google 日历。 为此,我创建了日历并将其公开。然后,我创建了一个 Google 服务帐户和相关的客户端 ID。 我还启用了日历 API 并将 v3 dll 添加到项目中。 我下载了 p12 证书,然后问题就开始了。

对 Google 的调用使用 X509 证书,但 .NET 框架的构建方式是它使用用户临时文件夹。 由于它是 Web 服务器 (GoDaddy) 的共享主机,因此我无法修改应用程序池标识。 结果,我收到了这个错误:

System.Security.Cryptography.CryptographicException:系统无法 找到指定的文件。

调用时:

X509Certificate2 certificate = new X509Certificate2(GoogleOAuth2CertificatePath,
                "notasecret", X509KeyStorageFlags.Exportable);

然后将在 google 调用中使用该证书 var:

ServiceAccountCredential credential = new ServiceAccountCredential(
                new ServiceAccountCredential.Initializer(GoogleOAuth2EmailAddress)
                {
                    User = GoogleAccount,
                    Scopes = new[] { CalendarService.Scope.Calendar }
                }.FromCertificate(certificate));

...但我从来没有走到那一步。

问题:有没有办法以不同的方式进行调用,即不使用 X509 证书而是使用 JSON? 或者我可以让 x509 函数使用一般临时位置,而不是我无法访问的用户位置,因为我无法更改应用程序池中的身份?

由于我完全陷入困境,因此将不胜感激。

【问题讨论】:

  • 使用 JSON 肯定会遇到同样的问题 - 问题是“我无法加载文件”,而不是 Google 或 X509 特定的问题。您可以将证书嵌入到程序集中并使用Assembly.GetManifestResourceStream 加载数据...
  • 同意您将 GoogleOAuth2CertificatePath 放在哪里?
  • .p12 文件位于 App_Data/MyGoogleStorage 文件夹中。
  • .p12 文件位于 App_Data/MyGoogleStorage 文件夹中。我可以在直接输入地址时下载文件,所以这不是路径或凭据问题。我也同意问题不在于 Google 本身,因为在实际创建 x509 证书时,我在通话之前被卡住了。 @Jon Skeet:我喜欢你的想法……请问你有代码示例吗?
  • “直接输入地址就可以下载文件”到底是什么意思?它不应该被您的网络应用程序公开...

标签: c#-4.0 google-api google-calendar-api google-api-dotnet-client service-accounts


【解决方案1】:

避免担心文件位置的一个简单选项是将证书嵌入到您的程序集中。在 Visual Studio 中,右键单击该文件并显示其属性。在 Build Action 下,选择“Embedded resource”。

然后您应该能够使用以下内容加载数据:

// In a helper class somewhere...
private static byte[] LoadResourceContent(Type type, string resourceName)
{
    string fullName = type.Namespace + "." + resourceName;
    using (var stream = type.Assembly.GetManifestResourceStream(fullName)
    {
        var output = new MemoryStream();
        stream.CopyTo(output);
        return output.ToArray();
    }
}

然后:

byte[] data = ResourceHelper.LoadResourceContent(typeof(MyType), "Certificate.p12");
var certificate = new X509Certificate2(data, "notasecret", X509KeyStorageFlags.Exportable);

这里MyType 是某种类型,它与您的资源位于同一文件夹中。

请注意,.NET 中有许多不同的“网络”项目类型...根据您使用的确切项目类型,您可能需要对此进行调整。

【讨论】:

  • 这是一个网页项目,所以我没有嵌入文件的选项,是吗?我在 VS2012 中唯一的属性是文件名和本地路径
  • @Nick:从您的描述中不清楚您使用的是哪种项目。您可以将其放入单独的类库中……或升级以使用功能更全面的 Web 项目……
  • 该站点是一个 .net 4.5 Web 应用程序
  • @Nick:对,如果它是一个 Web 应用程序,那么您应该能够毫无问题地添加资源。 (如果你使用的是 VS2012,那是 C# 5 而不是 C# 4,对吧?)
  • @Nick:我刚刚尝试过 - 诚然在 VS2015 中 - 创建一个新的 WebForms 应用程序,并添加一个文件......我能够很好地设置构建操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多