从驱动器获取文件时,传递用户以模拟身份

3
我创建了一个Web应用程序,并实现了Google登录功能。我想为它添加搜索功能,让用户可以搜索他/她的驱动器中存在的任何文件。在Google Drive API的示例代码中,应用程序打开浏览器窗口并提供凭据后,令牌被本地存储,我希望通过代码传递凭据,因此我为此创建了一个服务帐户。
Google文档中写道:您的应用程序现在拥有作为您域中的用户进行API调用的权限(“模拟”用户)。当您准备进行授权的API调用时,您需要指定要模拟的用户。 以下是我的代码-
static void Main(string[] args)
{
    try
    {
        var service = AuthenticateServiceAccountV1(GServiceAccount, "keycredentials.json");
        FilesResource.ListRequest listRequest = service.Files.List();
        listRequest.PageSize = 1000;
        listRequest.Fields = "nextPageToken, files(webViewLink, name, id)";
        IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;
        Console.WriteLine("Processing...\n");
        if (files != null && files.Count > 0)
        {
            var listfiles = files.Select(x => x.Id).ToList();
            Console.WriteLine(files.Count + " records fetched.");
        }
        else
        {
            Console.WriteLine("No files found.");
        }
        Console.ReadLine();
    }
    catch(Exception ex)
    {
        throw ex;
    }
}

static DriveService AuthenticateServiceAccountV1(string ServiceAccountEmail, string KeyFilePath)
{
    try
    {
        if (string.IsNullOrEmpty(KeyFilePath))
            throw new Exception("Path to the service account credentials file is required.");
        if (!File.Exists(KeyFilePath))
            throw new Exception("The service account credentials file does not exist at: " + KeyFilePath);
        if (string.IsNullOrEmpty(ServiceAccountEmail))
            throw new Exception("ServiceAccountEmail is required.");

        if (Path.GetExtension(KeyFilePath).ToLower() == ".json")
        {
            GoogleCredential credential;
            using (var stream = new FileStream(KeyFilePath, FileMode.Open, FileAccess.Read))
            {
                credential = GoogleCredential.FromStream(stream)
                     .CreateScoped(Scopes);
            }

            return new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            });
        }
        else if (Path.GetExtension(KeyFilePath).ToLower() == ".p12")
        {
            var certificate = new X509Certificate2(KeyFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
            ServiceAccountCredential credential = new ServiceAccountCredential(
                new ServiceAccountCredential.Initializer(ServiceAccountEmail)
                {
                    Scopes = Scopes,
                }.FromCertificate(certificate));

            return new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName
            });
        }
        else
        {
            throw new Exception("Unsupported Service accounts credentials.");
        }
    }
    catch (Exception ex)
    {
        return null;
    }
}

在上述代码中,我应该在哪里传递模拟用户的电子邮件地址?我的应用程序使用 g-suite 帐户。我尝试将 credential = GoogleCredential.FromStream(stream).CreateScoped(Scopes); 替换为 credential = GoogleCredential.FromStream(stream).CreateScoped(Scopes).CreateWithUser("userid@gmail.com"); 它会抛出异常,说:

{"Error:\"unauthorized_client\", Description:\"Client is unauthorized to retrieve access tokens using this method.\", Uri:\"\""}


尝试更改 CreateScopedCreateWithUser 的顺序。我不能解释为什么,但这对我起作用了。 - hultqvist
1个回答

0

{"Error:\"unauthorized_client\", Description:\"客户端未经授权使用此方法检索访问令牌。\", Uri:\"\""}

在 Google 开发者控制台中,您创建了一个带有凭据的项目。 凭据有两种类型,它们具有不同的文件和不同的代码需要使用它们。

您正在使用用于使用服务帐户进行身份验证的代码。 您正在使用的凭据文件可能是用于 Oauth2 的。 转到 Google 开发者控制台并创建不同的凭据类型,然后下载新文件。

ServiceAccount.cs

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);
            }
        }
    }

我没明白你在说什么。去谷歌开发者控制台创建一个不同的凭证类型并下载新文件。 - Sonali
这里 https://console.developers.google.com/ 可能会有帮助,但图片有点过时。 "keycredentials.json" <--- 是错误类型的凭据。 - Linda Lawton - DaImTo
我已经将我的文件重命名为 keycredentials.json - Sonali
@DalmTo 我已经按照这里提供的步骤进行了操作 https://developers.google.com/identity/protocols/OAuth2ServiceAccount - Sonali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接