在Google Drive API中使用服务帐户下载文件时未经授权的响应

时间:2014-05-30 00:00:06

标签: c# .net google-oauth google-api-dotnet-client google-drive-api

我正在使用以下代码从Google的身份验证服务器获取credentials以访问Google drive API

 public static Google.Apis.Services.BaseClientService.Initializer getCredentials()
    {

        String serviceAccountEmail = "xxx@developer.gserviceaccount.com";

        var certificate = new X509Certificate2(@"xxx.p12", "notasecret", X509KeyStorageFlags.Exportable);

        ServiceAccountCredential credential = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(serviceAccountEmail)
           {
               Scopes = new[] { DriveService.Scope.Drive }
           }.FromCertificate(certificate));



        return new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "AppName",
        };



    }

然后从文件元数据中检索下载URL并尝试使用以下代码下载该文件:

 public static System.IO.Stream DownloadFile(Google.Apis.Drive.v2.Data.File file, Google.Apis.Drive.v2.DriveService service)
   {



       if (!String.IsNullOrEmpty(file.DownloadUrl))
       {
           try
           {
               HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
                   new Uri(file.DownloadUrl));
              // authenticator.ApplyAuthenticationToRequest(request);
               HttpWebResponse response = (HttpWebResponse)request.GetResponse();
               if (response.StatusCode == HttpStatusCode.OK)
               {
                   return response.GetResponseStream();
               }
               else
               {
                   Console.WriteLine(
                       "An error occurred: " + response.StatusDescription);
                   return null;
               }
           }
           catch (Exception e)
           {
               Console.WriteLine("An error occurred: " + e.Message);
               return null;
           }
       }
       else
       {
           // The file doesn't have any content stored on Drive.
           return null;
       }
   }

但是我收到了401 unauthorized回复。我假设我需要在授权行中添加一个Authorization标头:Bearer {ACCESS_TOKEN}HttpClientInitializer.Token属性为null。是否可以使用ServiceAccountCredential

对此请求进行身份验证

2 个答案:

答案 0 :(得分:1)

您的代码有点偏差。我这一分钟没有服务帐户Google Drive API示例。对于Big Query来说,这几乎是一样的。

String serviceAccountEmail = "539621478854-imkdv94bgujcom228h3ea33kmkoefhil@developer.gserviceaccount.com";
var certificate = new X509Certificate2(@"C:\Users\linda_l\Documents\GitHub\GoogleBigQueryServiceAccount\GoogleBigQueryServiceAccount\key.p12", "notasecret", X509KeyStorageFlags.Exportable);

ServiceAccountCredential credential = new ServiceAccountCredential(
       new ServiceAccountCredential.Initializer(serviceAccountEmail)
          {
           Scopes = new[] { BigqueryService.Scope.DevstorageReadOnly }
          }.FromCertificate(certificate));

        // Create the service.
var service = new BigqueryService(new BaseClientService.Initializer()
      {
       HttpClientInitializer = credential,
       ApplicationName = "BigQuery API Sample",
       });

您能看到BaseClientService.Initializer()用于创建BigqueryService的位置。我想你需要创建一个GoogleDriveService。创建服务后,您应该能够使用该服务下载该文件。您不应该通过HTTPRequest来执行此操作。

我会在今晚使用Google云端硬盘找到更好的例子。

答案 1 :(得分:1)

我今天遇到了同样的问题。使用您的方法发出请求不提供身份验证标头。我需要以不同的方式构建请求。你在哪里:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
               new Uri(file.DownloadUrl));

你应该:

HttpResponseMessage response = await service.HttpClient.GetAsync(new Uri(file.DownloadUrl));

这可确保正确验证请求。