3

Googleサインインを実装したWebアプリケーションを作成しました。ユーザーが自分のドライブに存在する任意のファイルを検索できる検索機能を追加したいと考えています。Google Drive Api のサンプル コードでは、アプリがブラウザー ウィンドウを開き、資格情報を提供した後、トークンがローカルに保存されます。資格情報をコードで渡したいので、このためのサービス アカウントを作成しました。

google documentationでは、次のように書かれていますYour application now has the authority to make API calls as users in your domain (to "impersonate" users). When you prepare to make authorized API calls, you specify the user to impersonate.

これが私のコードです-

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

上記のコードで、なりすましユーザーの電子メール ID をどこで渡すことができますか? アプリケーションに g-suite アカウントを使用しています。と交換credential = GoogleCredential.FromStream(stream).CreateScoped(Scopes);してみましたcredential = GoogleCredential.FromStream(stream).CreateScoped(Scopes).CreateWithUser("userid@gmail.com");

それは言って例外を与えます

{"エラー:\"unauthorized_client\"、説明:\"クライアントは、このメソッドを使用してアクセス トークンを取得する権限がありません。\"、Uri:\"\""}

4

1 に答える 1

0

{"エラー:\"unauthorized_client\"、説明:\"クライアントは、このメソッドを使用してアクセス トークンを取得する権限がありません。\"、Uri:\"\""}

Google 開発者コンソールで、資格情報を使用してプロジェクトを作成しました。クレデンシャルには 2 つのタイプがあり、それらを使用するために必要なファイルとコードが異なります。

使用しているコードは、サービス アカウントで認証するためのものです。使用している資格情報ファイルは、おそらく 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);
            }
        }
    }
于 2018-03-21T10:23:37.133 に答える