Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticate to use Google Sheets with service account instead of personal account in C# .NET

Tags:

I have an application that I developed that utilizes a few Google Sheets.

I was able to figure out how to get it to have access to the Google Sheets API using the following code:

    UserCredential credential;
    using (var stream =
                  new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
    {
        string credPath = System.Environment.GetFolderPath(
            System.Environment.SpecialFolder.Personal);


        credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
            GoogleClientSecrets.Load(stream).Secrets,
            Scopes,
            "user",
            CancellationToken.None,
            new FileDataStore(credPath, true)).Result;
        Console.WriteLine("Credential file saved to: " + credPath);
    }
    // Create Google Sheets API service.
    var service = new SheetsService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = ApplicationName,
    });

This application will be used by a few other people - but the first time they run the application it asks them to login to Google - but their accounts don't give them the appropriate access.

I think (correct me if I'm wrong) - using a Service Account should resolve my issue and no longer prompt a user to 'login', but still allow my application to read/update the Sheets appropriately.

I'd like to take my existing code and modify it to use a Service Account but I can't find any good documentation on how to do that. I have created the Service Account and have the ServiceAccount.json file in the same spot as the current 'client_secret.json' file but am unsure how to proceed much further.

I have tried changing the code to:

    ServiceAccountCredential credential;
    //UserCredential credential;
    using (var stream =
        new FileStream("HelperServiceAccount.json", FileMode.Open, FileAccess.Read))
    {
        string credPath = System.Environment.GetFolderPath(
            System.Environment.SpecialFolder.Personal);


        credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
            GoogleClientSecrets.Load(stream).Secrets,
            Scopes,
            "user",
            CancellationToken.None,
            new FileDataStore(credPath, true)).Result;
            )
        Console.WriteLine("Credential file saved to: " + credPath);
    }
    // Create Google Sheets API service.
    var service = new SheetsService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = ApplicationName,
    });

But it fails - the credential variable gives an error.

Any ideas?

like image 419
Hanny Avatar asked Dec 21 '16 16:12

Hanny


1 Answers

You should have created the service account and stored the json credential file:

Then try this:

        ServiceAccountCredential credential;
        string[] Scopes = { SheetsService.Scope.Spreadsheets };
        string serviceAccountEmail = "[email protected]";
        string jsonfile = "xxxxxxxx-xxxxxxx.json";
        using (Stream stream = new FileStream(@jsonfile, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            credential = (ServiceAccountCredential)
                GoogleCredential.FromStream(stream).UnderlyingCredential;

            var initializer = new ServiceAccountCredential.Initializer(credential.Id)
            {
                User = serviceAccountEmail,
                Key = credential.Key,
                Scopes = Scopes
            };
            credential = new ServiceAccountCredential(initializer);
        }
like image 132
D Joyce Avatar answered Sep 23 '22 18:09

D Joyce