0
votes

I am trying to upload the files to google drive. For this I have an service account with domain wide authority enabled. "@xyx.com" is my domain. I have a common "[email protected]" google drive.

Google service account is "[email protected]". I need to upload the files to "[email protected]". I tried to impersonate the "[email protected]" to the service account.

Below is my code

public static DriveService AuthenticateServiceAccount(string serviceAccountEmail, string keyFilePath)
        {
            // check the file exists
            if (!File.Exists(keyFilePath))
            {
                return null;
            }

            //Google Drive scopes Documentation:   https://developers.google.com/drive/web/scopes
            string[] scopes = new string[] { DriveService.Scope.Drive,  // view and manage your files and documents
                                             DriveService.Scope.DriveAppdata,  // view and manage its own configuration data
                                             DriveService.Scope.DriveFile,   // view and manage files created by this app
                                             DriveService.Scope.DriveMetadata,
                                             DriveService.Scope.DriveMetadataReadonly,   // view metadata for files
                                             DriveService.Scope.DrivePhotosReadonly,
                                             DriveService.Scope.DriveReadonly,   // view files and documents on your drive
                                             DriveService.Scope.DriveScripts };  // modify your app scripts     


            var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
            try
            {
                ServiceAccountCredential credential = new ServiceAccountCredential(
                    new ServiceAccountCredential.Initializer(serviceAccountEmail)
                    {
                        Scopes = scopes,
                        User = "[email protected]",
                    }.FromCertificate(certificate));
                DriveService service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "CIM_GD_UPLOAD",
                });
                return service;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

I am getting the following error.

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

I am using google api v3.

Please help me, is it possible to impersonate an user account to a service account? or guide me the correct way to upload/ retrieve the files from google drive.

1
you need to have the whole thing setup through G-Suite - in case that wasnt done. - Spacemonkey
did you found any solution for this ? - Siddharth Vaghasia

1 Answers

-1
votes

Referring to Google Drive API Authorization, you need to authorize request with OAuth 2.0 to be able to access Google APIs. First step in the authorization process is to obtain OAuth 2.0 credentials from the Google API Console. Same process goes when you use service account, you have to generate service-account credentials then delegate domain-wide authority to the service account.

You may want to try as stated in this documentation:

If you have delegated domain-wide access to the service account and you want to impersonate a user account, specify the email address of the user account with the setServiceAccountUser method of the GoogleCredential factory. For example:

GoogleCredential credential = new GoogleCredential.Builder()
    .setTransport(httpTransport)
    .setJsonFactory(JSON_FACTORY)
    .setServiceAccountId(emailAddress)
    .setServiceAccountPrivateKeyFromP12File(new File("MyProject.p12"))
    .setServiceAccountScopes(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .setServiceAccountUser("[email protected]")
    .build();

Use the GoogleCredential object to call Google APIs in your application.