0

I am trying to use Google Calendar API to access the calendar of various users in our organization calendars using OAuth2.0 and a service account but I get an error

"invalid_request" "Invalid impersonation prn email address.".

In the Google console I have:
- Created a project
- Created a service account and enabled "Domain wide delegation" and given the "Project Owner" role, then got a P12 key.
- In Security > Advanced settings > Authentication > Manage API client access I have given the serviceaccount access to https://www.googleapis.com/auth/calendar.readonly.

using System;
using System.Windows.Forms;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Services;
using System.Security.Cryptography.X509Certificates;

namespace Google_Calendar
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button2_Click(object sender, EventArgs e)
    {
      string GoogleCertificate = @"testcalendar-209521-772939e76cae.p12"; // keyfile filename 
      string GoogleEmail = @"myserviceaccount@testcalendar-209521.iam.gserviceaccount.com"; // serviceaccount mail
      string GoogleUser = "MyServiceAccount"; // serviceaccount name
      string[] Scopes = new string[] { "https://www.googleapis.com/auth/calendar.readonly" };

      X509Certificate2 certificate = new X509Certificate2(GoogleCertificate, "notasecret", X509KeyStorageFlags.Exportable);
      ServiceAccountCredential credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer(GoogleEmail)
        {
          Scopes = Scopes,
          User = GoogleUser
        }.FromCertificate(certificate));
      CalendarService service = new CalendarService(new     BaseClientService.Initializer() { HttpClientInitializer = credential,     ApplicationName = "testcalendar" });

      string CalenderID = "mathias@mydomain.com";
      var CalRequest = service.Events.List(CalenderID);
      CalRequest.TimeMin = DateTime.Now.AddMonths(-1); //optional parameter
      CalRequest.TimeMax = DateTime.Now.AddMonths(+1); //optional parameter
      do
      {
        var events = CalRequest.Execute();  // here I get the error
        foreach (var item in events.Items)
        {
          // do stuff
        }
        CalRequest.PageToken = events.NextPageToken;
      } while (CalRequest.PageToken != null);
    }
  }
}

Any ideas what the problem might be? I think the problem is in my settings in Google somewhere. Do I miss a step there?

Jon R.
  • 1
  • 3
  • The user email configured in the platform is incorrect or doesn’t exist in your G Suite. – Linda Lawton - DaImTo Jul 09 '18 at 09:09
  • The user email mathias@example.com does exist in my G Suite. (But I get the same error if I use a non existing email address) The address is the primary mail address and the user is active. – Jon R. Jul 09 '18 at 09:47
  • and the service account has access to Gsuite? – Linda Lawton - DaImTo Jul 09 '18 at 10:05
  • Do I need to give the service account any access in addition to what I did in _Security > Advanced settings > Authentication > Manage API client access_ where I gave the serviceaccount access to _https://www.googleapis.com/auth/calendar.readonly_? – Jon R. Jul 09 '18 at 10:47
  • https://developers.google.com/admin-sdk/directory/v1/guides/delegation https://developers.google.com/calendar/auth#perform-g-suite-domain-wide-delegation-of-authority – Linda Lawton - DaImTo Jul 09 '18 at 11:18
  • Yes, when I created the service account I enabled "Domain wide delegation" and then I delegated domain-wide authority to the service account as described in the article. – Jon R. Jul 09 '18 at 12:07

1 Answers1

0

With some help from Google support I solved the problem(s).

1: Where I had used the service account user
string GoogleUser = "MyServiceAccount";
I should have used an impersonate user
string GoogleUser = "MyAdminUser";

2: When I added the scopes on my Admin Console, I added it by using the Service Account email, which then got translated visually to the ClientID of my Project and everything seemed to be ok. But it was not. When I instead used the ClientID everything worked correct.

Jon R.
  • 1
  • 3