1

我正在使用 .NET google 客户端库中的 Google DRIVE API,并希望从服务帐户中模拟用户。我读过许多其他面临同样问题的用户,但没有一个修复对我有用。下面是详细信息。

  1. 创建服务帐户并启用域范围的委派(现在超过 3 小时)。
  2. 下载 *.p12 文件并记下密码
  3. 使用服务帐户客户端 ID 添加了权限驱动范围
  4. 使用以下代码创建服务并从谷歌驱动器上传/获取数据

代码

var certificate = new X509Certificate2(keyfilepath, "notasecret", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

            string[] scopes = new string[] {
        DriveService.Scope.Drive,
        DriveService.Scope.DriveFile,
        DriveService.Scope.DriveAppdata,
        DriveService.Scope.DriveMetadata
        };

            var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceaccountemail)
            {
                Scopes = scopes,
                User = "abcr@mydomain.com"


            }.FromCertificate(certificate));
            // Create the service.
            var service = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "Drive API Sample"

                //HttpClientFactory = new ProxySupportedHttpClientFactory()

            });



var keyname = "1231312.p12";
var newservicact = "asdfasdf@gsuite-migration-4564654.iam.gserviceaccount.com";

            _service = this.AuthorizeServiceAccountwithMimic(newservicact,keyname);


 Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File();
 body.Name = System.IO.Path.GetFileName(_uploadFile);
body.Description = _descrp;
 body.MimeType = GetMimeType(_uploadFile);
body.Properties = customcolumns;



byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
                System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
                try
                {
                    FilesResource.CreateMediaUpload request = _service.Files.Create(body, stream, GetMimeType(_uploadFile));

                    request.SupportsTeamDrives = true;


                    request.ProgressChanged += Request_ProgressChanged;
                    request.ResponseReceived += Request_ResponseReceived;

                    request.Upload();

                    return request.ResponseBody;
                }

在 Request_ProgressChanged 事件中发送的第一批数据时,我遇到了错误。

执行 google API 方法时,它会抛出错误

错误:“unauthorized_client”,描述:“客户端未经授权无法使用此方法检索访问令牌。”,Uri:“”

我已经检查了许多启用 DWD 的论坛和 aaded 应用程序范围......任何人有任何想法请帮助,

4

1 回答 1

0

有几种方法可以访问 google api。使用 Oauth2 并使用服务帐户。

为服务帐户创建的客户端和使用的代码不同于为浏览器应用程序创建的客户端以及用于对其进行身份验证的代码。如果你去谷歌开发者控制台并创建一个浏览器客户端,你不能使用这个客户端的服务帐户代码。具有浏览器客户端 ID 的服务帐户代码也是如此。

错误:“unauthorized_client”,描述:“客户端未经授权无法使用此方法检索访问令牌。”,Uri:“”

基本上意味着您使用的客户端不是您使用的代码的正确类型。

返回 google 开发者控制台 创建服务帐户 下载服务帐户 .json 文件

服务帐户.cs

using Google.Apis.Drive.v3;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;

namespace GoogleSamplecSharpSample.Drivev3.Auth
{

    public static class ServiceAccountExample
    {

        /// <summary>
        /// Authenticating to Google using a Service account
        /// Documentation: https://developers.google.com/accounts/docs/OAuth2#serviceaccount
        /// </summary>
        /// <param name="serviceAccountEmail">From Google Developer console https://console.developers.google.com</param>
        /// <param name="serviceAccountCredentialFilePath">Location of the .p12 or Json Service account key file downloaded from Google Developer console https://console.developers.google.com</param>
        /// <returns>AnalyticsService used to make requests against the Analytics API</returns>
        public static DriveService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath, string[] scopes)
        {
            try
            {
                if (string.IsNullOrEmpty(serviceAccountCredentialFilePath))
                    throw new Exception("Path to the service account credentials file is required.");
                if (!File.Exists(serviceAccountCredentialFilePath))
                    throw new Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath);
                if (string.IsNullOrEmpty(serviceAccountEmail))
                    throw new Exception("ServiceAccountEmail is required.");                

                // For Json file
                if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
                {
                    GoogleCredential credential;
                    using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
                    {
                        credential = GoogleCredential.FromStream(stream)
                             .CreateScoped(scopes);
                    }

                    // Create the  Analytics service.
                    return new DriveService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "Drive Service account Authentication Sample",
                    });
                }
                else if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".p12")
                {   // If its a P12 file

                    var certificate = new X509Certificate2(serviceAccountCredentialFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
                    var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
                    {
                        Scopes = scopes
                    }.FromCertificate(certificate));

                    // Create the  Drive service.
                    return new DriveService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "Drive Authentication Sample",
                    });
                }
                else
                {
                    throw new Exception("Unsupported Service accounts credentials.");
                }

            }
            catch (Exception ex)
            {                
                throw new Exception("CreateServiceAccountDriveFailed", ex);
            }
        }
    }
}

如果它仍然不起作用,则意味着您没有正确配置域范围的委托给服务帐户委托授权

于 2018-10-30T14:03:57.643 回答