Search code examples
c#google-drive-apigoogle-oauthservice-accounts

Invalid authentication credentials when trying to list google drive folder from C# app


I'm attempting to write a simple C# .NET application that lists the contents of a Google Drive Folder using Google APIs v1.68.

I've done the following setup:

  • Created a project in Google Cloud
  • Created a service account for that project
  • Created a key for that service account and downloaded it
  • Ensured my test google drive folder has read permission for the service account (using the email address provided by google cloud)
  • Wrote the following code and got it to compile:
    public class GoogleDriveService
    {
        public struct FileInfo
        {
            public string id;
            public string name;
            public string mimeType;
        }
        private readonly DriveService _driveService;

        public GoogleDriveService(string serviceAccountJsonPath, string applicationName)
        {
            using (var stream = new System.IO.FileStream(serviceAccountJsonPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                var serviceAccountCredential = ServiceAccountCredential.FromServiceAccountData(stream);
                _driveService = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = serviceAccountCredential,
                    ApplicationName = applicationName
                });
            }
        }

        public async Task<List<FileInfo>> ListFolderContents(string folderId)
        {
            var request = _driveService.Files.List();
            request.Q = $"parents = '{folderId}'";
            request.Fields = "nextPageToken, files(id, name, mimeType)";

            var files = new List<File>();
            do
            {
                var response = await request.ExecuteAsync();
                files.AddRange(response.Files);
                request.PageToken = response.NextPageToken;
            } while (!string.IsNullOrEmpty(request.PageToken));

            var fileInfoList = new List<FileInfo>();

            foreach(File file in files)
            {
                fileInfoList.Add(new FileInfo()
                {
                    id = file.Id,
                    name = file.Name,
                    mimeType = file.MimeType
                });
            }

            return fileInfoList;
        }
    }

When I run the file list request, I get an exception set

The service drive has thrown an exception. HttpStatusCode is Unauthorized. Google.Apis.Requests.RequestError Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.

Please help me resolve this error. (Code samples rather than directions to documentation would be appreciated, as I've tried but failed to understand the documents, and this is only a small part of my project.)


Solution

  • Got it!

    Setting the scope for the service account credential is all that is needed:

        _serviceAccountCredential.Scopes = new string[]
        {
            Google.Apis.Drive.v3.DriveService.Scope.DriveReadonly
        };
    

    I can now read the contents of my google drive folder.

    [I know the StackOverflow rules prohibit answers generated by AI, but hats off to Gemini to pointing me in the right direction when I asked how to generate the token. It pointed me to this answer in StackOverflow.]