我们在1年多前写了一个软件来同步谷歌日历中的事件。它自2018年3月以来一直在运作,但它本月已停止在我们为我们和我们的客户使用的每个Gsuite实例上停止工作。
问题是我们使用服务帐户通过Google CalendarAPI v3访问日历资源事件。使用服务帐户凭据进行身份验证后,对于每个服务调用,我们现在都会遇到错误:
“错误:\”invalid_request \“,说明:\”校长必须是电子邮件地址\“,Uri:\”\“”
我无法在任何地方找到这个问题的答案,这听起来像是Google服务的政策变更,但我无法确定这一点。 Google API似乎在抱怨服务帐户电子邮件,这实际上并不是真正有效的电子邮件。它采用以下格式:
mydomain.com_(client_id)313 ....... @ resource.calendar.google.com
您认为问题可能与服务帐户电子邮件地址有关吗?为什么它在四月之前工作,现在停止工作?
一种可能的解决方案,尚未尝试:
我播种可以使用“委托”作为服务帐户。如果我尝试使用有效的用户电子邮件并将其委托给我的服务帐户,会发生什么?
/* function I use to authenticate my service account to Google Calendar
* service. serviceAccount is the email (Principal not working?) and json is
* the key generated for him.
*/
public void bindCalendarService(string json, string serviceAccount)
{
var cr = Newtonsoft.Json.JsonConvert.DeserializeObject<PersonalServiceAccountCred>(json);
ServiceAccountCredential xCred = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(cr.client_id, cr.token_uri)
{
Scopes = new string[] {
CalendarService.Scope.Calendar,
},
User = serviceAccount
}.FromPrivateKey(cr.private_key));
CalendarService calendarService = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = xCred
});
this.calendarService = calendarService;
}
你需要在谷歌帐户安全上访问不安全的应用程序,试试这个:https://support.google.com/accounts/answer/6010255?hl=en,如果它不工作与我说话。
我今天以另一种方式解决问题。
1)我试图实现如下所述的委托:https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority它的工作原理。
2)没有委托,我以这种方式改变上面列出的方法:
var credentialParameters = NewtonsoftJsonSerializer.Instance.Deserialize(json);
ServiceAccountCredential xCred = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(**credentialParameters.ClientEmail**)
{
Scopes = new string[] {
CalendarService.Scope.Calendar
},
User = serviceAccount, // service account's email
}.FromPrivateKey(credentialParameters.PrivateKey));
它甚至以这种方式工作。为什么上面的代码在1年后停止工作仍然是个谜。
希望它会帮助别人谢谢